Debug mode is the first thing to enable when starting any Odoo development or troubleshooting session. It unlocks the Technical menu, shows field metadata on hover, enables the XML editor on views, and exposes the built-in profiler. Most support calls and debugging sessions could be shorter if the developer knew what debug mode reveals.
This post covers every activation method, every technical menu section that matters, and how to use the profiler to find slow server-side code.
Activating debug mode#
Method 1: URL parameter#
Append ?debug=1 (or ?debug=assets) to any Odoo URL:
https://myodoo.com/web#action=mail.action_discuss&debug=1
https://myodoo.com/odoo/sales?debug=1debug=1 enables standard debug mode. debug=assets additionally disables JS/CSS bundling, loading individual source files - slower but required for browser devtools to show the correct file names and line numbers.
Method 2: Settings toggle#
Go to Settings → scroll to the bottom → Developer Tools → Activate the developer mode.
Method 3: URL shortcut via about:debug#
Navigate to /web?debug=1 (just the path, no hash) - this forces debug mode and redirects to the home page.
Method 4: Keyboard shortcut (Odoo 17)#
In Odoo 17+, press Alt+D on any page to toggle debug mode.
Disabling debug mode#
Replace debug=1 with debug=0 in the URL, or go to Settings → Developer Tools → Deactivate the developer mode.
What debug mode enables#
Bug icon (top-right corner)#
The debug icon (a bug) appears in the top action bar. Click it for quick access to view metadata, technical info, and mode switching.
Field tooltips#
Hover over any field label to see the field's technical name, type, and module origin. This is the fastest way to find field names when writing domain filters or Python code.
View XML editor#
In the debug icon dropdown: Edit View: Form View (or list, kanban, etc.) opens the XML source editor with a diff view - you can see the final merged XML after all view inheritance is applied. This is invaluable for debugging XPath inheritance issues.
Duplicate/delete views#
Debug mode enables the Duplicate button on views, which is the correct way to test customisations without modifying the base view directly.
Technical menu#
Debug mode adds a Technical item to the Settings menu. The most useful sub-menus:
Database Structure#
| Sub-menu | Use |
|---|---|
| Models | Browse all installed models; click a model to see its fields, methods, and access rights |
| Fields | Search and filter all fields across all models |
| Constraints | List Python and SQL constraints |
The Models menu is the fastest way to inspect an unfamiliar model. You can see every field (including non-stored computed fields), the field type, and whether it was added by a custom module.
Security#
| Sub-menu | Use |
|---|---|
| Users | Full user list with groups; edit directly from here |
| Groups | All security groups with implied groups and users |
| Access Rights | ir.model.access - CRUD permissions per group/model |
| Record Rules | ir.rules - domain-based row filters |
These are the primary tools for debugging access denied errors (see the security model guide).
Actions#
| Sub-menu | Use |
|---|---|
| User Interface → Actions → Window Actions | ir.actions.act_window - view all window actions, modify domain/context |
| User Interface → Actions → Server Actions | ir.actions.server - automated actions |
| User Interface → Actions → Client Actions | ir.actions.client - OWL client action registrations |
| User Interface → Views | All views by type and model; edit XML |
| User Interface → Menus | Full menu tree; modify visibility and action assignments |
The Views menu lets you search for views by model or type and open the XML editor without navigating to the model first.
Sequences & Identifiers#
Technical → Sequences & Identifiers → Sequences - all ir.sequence records. See the current counter, modify prefix, reset the counter (see the ir.sequence guide).
Email#
| Sub-menu | Use |
|---|---|
| Outgoing Mail Servers | Configure SMTP; test connection |
| Incoming Mail Servers | POP3/IMAP fetchmail configuration |
| Email Templates | All mail.template records; edit body/subject |
| Email: Messages | mail.message log; see all sent and received messages |
The Email: Messages menu is how you verify that a triggered email was actually sent - check the State column (outgoing vs sent vs exception).
Automation#
| Sub-menu | Use |
|---|---|
| Automated Actions | base_automation.rule - trigger-based automations |
| Scheduled Actions | ir.cron - time-based background jobs |
Check Scheduled Actions when a background job appears to not be running. Confirm the Active flag is checked and the Next Execution Date is in the future.
Translations#
| Sub-menu | Use |
|---|---|
| Languages | Installed language packs |
| Translations | ir.translation - all translated strings; search by source text |
Use the Translations menu to find missing translations or to override a UI string for a specific language without writing a custom module.
The built-in profiler#
Odoo 16+ includes a server-side Python profiler accessible from debug mode.
Enabling profiling#
- Enable debug mode
- Click the bug icon → Activate profiling (or add
?profiling=1to the URL in Odoo 17) - Perform the slow operation
- Click Open profiler (or go to Settings → Technical → Profiler)
Reading the flamegraph#
The profiler produces a flamegraph showing wall time and SQL query counts per stack frame. The most actionable columns:
| Column | Meaning |
|---|---|
| Wall time | Total elapsed time including I/O and waits |
| Sql count | Number of SQL queries; high numbers indicate N+1 problems |
| Sql time | Time spent in database |
Click any stack frame to zoom in. Look for frames with high SQL count relative to their children - those indicate redundant queries that could be batched.
Profiling from code (Odoo 16+)#
from odoo.tools.profiler import profile
class SaleOrder(models.Model):
_inherit = 'sale.order'
@profile
def action_confirm(self):
return super().action_confirm()This decorator profiles the method and stores the result in ir.profile. Access results via Settings → Technical → Profiler → Profiles.
Developer mode in production#
Debug mode should not be left active for non-technical users in production:
- It exposes the Technical menu which allows direct data modification
- Field tooltips display internal field names (minor information exposure)
- It disables some client-side validation intended to prevent user error
Restrict debug mode activation to users with the Administration / Settings group (base.group_system). In Odoo 16+, add the system parameter web.debug.enabled = 0 to block URL-based activation for non-admin users.
Asset debug mode (debug=assets)#
debug=assets disables Odoo's JS/CSS bundling. Use it when:
- You need browser devtools to show the actual source file (not
bundle.jsline 1) - You are debugging a JS error and the minified stack trace is unreadable
- You are checking whether a new asset file is being loaded correctly
Page load is 5–10x slower in debug=assets mode due to the number of individual requests. Never use it as the default debug mode.
Common debug mode tasks#
Finding a field's technical name: Enable debug mode → hover the field label → the tooltip shows field_name (field.type).
Checking why an action failed: Settings → Technical → Actions → Server Actions → find the action → run it manually from the action form.
Verifying an email was sent: Settings → Technical → Email → Messages → filter by model + record ID.
Checking which groups a user belongs to: Settings → Users & Companies → Users → select user → Groups tab (visible in debug mode).
Finding what view is rendered: Bug icon → Edit View → opens the merged XML with the final result of all XPath inheritance.
Resetting a sequence counter: Settings → Technical → Sequences & Identifiers → find sequence → edit number_next_actual.
For the full security model see the Odoo security model guide. For view XML inheritance and XPath see the view inheritance guide. For automated actions and scheduled actions see the automated actions guide.

