Understanding AccessError
Odoo has three access layers that can each throw AccessError. Understanding which layer caused the error is the key to fixing it quickly.
Layer 1: Model Access (ir.model.access)
Error Message
AccessError: You are not allowed to access 'Sale Order' (sale.order) records.
This operation is allowed for the following groups:
- Sales / User: Own Documents OnlyCause
The user's security groups do not have read/write/create/delete permission on this model.
Diagnosis
# Check what groups the user belongs to:
user = self.env['res.users'].browse(user_id)
print(user.groups_id.mapped('full_name'))
# Check model access rules:
SELECT g.name, a.perm_read, a.perm_write, a.perm_create, a.perm_unlink
FROM ir_model_access a
JOIN ir_model m ON a.model_id = m.id
LEFT JOIN res_groups g ON a.group_id = g.id
WHERE m.model = 'sale.order';Fix
# Option A: Add user to the correct group
# Settings → Users → select user → add Sales / User group
# Option B: Add access rule for user's existing group
# security/ir.model.access.csv:
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sale_order_user,sale.order.user,sale.model_sale_order,base.group_user,1,0,0,0Layer 2: Record Rules (ir.rule)
Error Message
AccessError: Due to security restrictions, you are not allowed to access
'Sale Order' (sale.order) records.
Records: SO/2026/0042
User: [email protected] (uid=15)Cause
The user has model-level access but a record rule restricts which specific records they can see.
Diagnosis
# Check record rules for this model:
SELECT r.name, r.domain_force, r.perm_read, r.perm_write,
CASE WHEN r.global THEN 'Global' ELSE 'Group' END as type
FROM ir_rule r
JOIN ir_model m ON r.model_id = m.id
WHERE m.model = 'sale.order' AND r.active = True;
# In Python:
rules = self.env['ir.rule'].search([
('model_id.model', '=', 'sale.order'),
('active', '=', True),
])
for rule in rules:
print(f"{rule.name}: {rule.domain_force} (groups: {rule.groups.mapped('name')})")Common Record Rule Issues
| Issue | Cause | Fix |
|---|---|---|
| User can't see other people's records | Rule: [('user_id','=',user.id)] | Change to team lead role or add broader rule |
| Multi-company data invisible | Rule: [('company_id','in',company_ids)] | Add user to the correct company |
| Portal user blocked | Portal rule too restrictive | Check portal-specific record rules |
| Global rule blocks admin | Global rules apply to everyone | Change global rule domain or convert to group rule |
Layer 3: Field-Level Access
Error Message
AccessError: You do not have enough rights to access the fields "purchase_cost"
on sale.order. Please contact your system administrator.Cause
The field has a groups attribute restricting access to specific security groups.
Diagnosis
# In Python model:
purchase_cost = fields.Float(groups='account.group_account_manager')
# In XML view:
<field name="purchase_cost" groups="account.group_account_manager"/>
# Check which group is required:
grep -r 'groups=' addons/sale/models/ | grep purchase_costFix
Add the user to the required group, or remove the groups attribute if the restriction is not needed.
Special Case: sudo() and Access
# WRONG — using sudo() to bypass access errors:
records = self.env['sale.order'].sudo().search([]) # BAD!
# RIGHT — fix the actual permissions:
# 1. Identify which layer blocks access
# 2. Fix the model access, record rule, or field group
# 3. Use sudo() ONLY for legitimate elevated operationsSpecial Case: Portal Users
# Portal users have limited access by default.
# They can only see records shared with them via portal rules.
# Common portal access issues:
# - Customer can't see their invoices → check portal sharing
# - Customer can't see their orders → verify portal rule domain
# - Customer gets 403 on portal → check portal group assignment
# Portal record rule example:
# domain: [('message_partner_ids', 'child_of', [user.commercial_partner_id.id])]Special Case: API / XML-RPC Access
# API users get the same access as their security groups.
# If API calls fail with AccessError:
# 1. Check the API user's groups
# 2. Check record rules for the API user
# 3. Consider creating a dedicated API user with appropriate groups
# Do NOT make the API user admin — grant only needed groupsSystematic Diagnosis Steps
- Read the exact error message — it tells you the model and often the blocking rule
- Enable Developer Mode → check the user's groups
- Check ir.model.access for the model + user's groups
- Check ir.rule for record-level restrictions
- Check field
groupsattributes - Check if it is a multi-company issue
- Check if it is a portal user issue
DeployMonkey
DeployMonkey's AI agent diagnoses AccessError automatically. Paste the error traceback, and it identifies the exact layer (model access, record rule, or field group), the blocking rule, and the fix.