Cet article est actuellement disponible en anglais uniquement. Traduction à venir.
By the end of this recipe, you will be able to inspect, decode, and replay any Odoo 19 RPC call from the Chrome DevTools Network tab, debug obscure "Server Error" messages by reading the actual server traceback, and profile slow-loading views by identifying the exact RPC contributing to the delay. Skill required: comfort with browser DevTools + basic Python tracebacks. Time required: 20 minutes to learn the pattern, indefinite payoff. ECOSIRE engineers reach for these techniques every day, and the recipe below is the playbook.
The reason "Server Error" with no details is the most-feared Odoo message: by default Odoo doesn't expose tracebacks to the browser. They're in the server log on the back end. The recipe below shows how to flip the developer mode to surface tracebacks AND how to read them efficiently in the Network tab.
What you will need
- Chrome or Firefox DevTools (any modern browser with Network tab).
- Odoo administrator access to enable developer mode.
- Time: 20 minutes to learn.
Step-by-step
1. Enable developer mode with assets
URL bar: https://your-odoo.com/web?debug=assets. The assets flag also stops minifying JS/CSS, so any error stack traces show real file names + line numbers.
For everyday debugging (without re-loading all assets), use https://your-odoo.com/web?debug=1. Verification: a "DEBUG" indicator appears in the URL bar or the user menu shows developer options.
2. Open the Network tab
F12 > Network tab > tick "Preserve log" so navigation doesn't clear the log. Click "XHR" or "Fetch" filter — Odoo RPC calls are JSON POSTs to /web/dataset/call_kw.
Verification: opening any list view triggers a flurry of call_kw requests visible in the panel.
3. Read an RPC payload
Click any /web/dataset/call_kw row. The Headers tab shows method, URL, status. The Payload tab shows JSON with shape:
{
"jsonrpc": "2.0",
"method": "call",
"params": {
"model": "sale.order",
"method": "search_read",
"args": [
[["state", "in", ["sale", "done"]]],
["id", "name", "partner_id", "amount_total", "state"]
],
"kwargs": {
"context": {
"lang": "en_US",
"tz": "UTC",
"uid": 2
},
"limit": 80
}
}
}
This tells you: model = sale.order, method = search_read, domain = state in (sale, done), fields requested, page limit 80.
Verification: you can read off the model and method from any payload.
4. Read an error response
When something fails, the Response tab shows JSON like:
{
"jsonrpc": "2.0",
"error": {
"code": 200,
"message": "Odoo Server Error",
"data": {
"name": "psycopg2.errors.InvalidTextRepresentation",
"message": "invalid input syntax for type integer: \"abc\"",
"context": {},
"debug": "Traceback (most recent call last):\n File \"...\", line 123\n ...\n",
"exception_type": "internal_error"
}
}
}
The data.debug field is the full Python traceback. Read it bottom-up: the innermost frame is usually where the bug is.
Verification: you can identify the failing line of Python from the error response.
5. Replay an RPC manually
Right-click the row > "Copy as cURL". Paste in terminal. The cURL replays the exact request:
curl 'https://your-odoo.com/web/dataset/call_kw' \
-H 'Cookie: session_id=...' \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","method":"call","params":{"model":"sale.order",...}}'
Tweak the payload and re-run to test variations. Verification: the cURL response matches the original DevTools response.
6. Use the Performance tab for slow views
For "this page loads slow" complaints, open the Performance tab, click record, refresh the page, stop record. The flame graph shows JavaScript time. The Network tab on the same page shows server time. Combine to find:
- Slow server (server > 500 ms): server-side bottleneck, look at Postgres query log.
- Slow JS (long Tasks > 50 ms): client-side bottleneck, profile with Chrome's CPU sampler.
- Many small RPCs (N+1 problem): client is firing one RPC per record instead of batching.
Verification: you correctly classify the bottleneck.
7. Enable server-side query logging
In odoo.conf:
log_level = info
log_db = production
log_handler = :INFO,odoo.sql_db:DEBUG
Restart Odoo. Now every SQL query logs with timing. Tail the log:
tail -f /var/log/odoo/odoo.log | grep -E "DEBUG|EXCEPTION"
Find slow queries:
grep "took [1-9][0-9]\{3,\}ms" /var/log/odoo/odoo.log | head
Verification: queries slower than 1 second show up — these are the optimization candidates.
8. Use odoo-bin shell for hypothesis testing
When you've narrowed the problem to a specific method, replicate it offline:
sudo -u odoo /opt/odoo/odoo-bin shell -c /etc/odoo/odoo.conf -d production
>>> orders = self.env['sale.order'].search([('state','=','sale')])
>>> import time; t = time.time(); orders.read(['amount_total']); print(time.time()-t)
0.234
This isolates the slowness from the browser/network and lets you test fixes interactively.
Verification: you can reproduce the slow operation in shell.
Common mistakes
- Forgetting
?debug=1. You see "Server Error" with no details and waste hours. - Reading tracebacks top-down. The bottom frame is usually the actual bug.
- Not preserving log on navigation. RPCs disappear when the page reloads.
- Confusing client time and server time. Look at the "Time" column; Chrome shows total but the breakdown into TTFB + content download distinguishes server vs network slowness.
- Skipping CORS preflights. OPTIONS requests show 0ms but block the actual call.
Going further
Profile a single RPC server-side: add import cProfile; cProfile.runctx('self._do_thing()', globals(), locals()) to a temporary debug version of the method. Output the profile to /tmp/profile.out and visualize with snakeviz for a flame-graph view of where the method spends its time.
Lighthouse audit: Chrome's Lighthouse panel scores Performance, Best Practices, SEO. Useful for identifying client-side optimizations. A score below 50 on Performance for a backend Odoo page indicates major issues — often unbatched RPCs or oversized JS bundles.
Network throttling: simulate slow 3G to see how the UI degrades. Reveals UX issues with synchronous RPCs that hang the UI for seconds. Configure in DevTools > Network > Throttling.
WebSocket debugging: Odoo's longpoll/websocket traffic shows in the WS filter. Useful for chat/notifications debugging. Each frame shows direction (incoming/outgoing), payload, and timing. Critical for diagnosing missing notifications or slow chat updates.
Session storage inspection: DevTools > Application > Session Storage shows the cached values. Odoo caches view definitions and similar artifacts here; clearing this can resolve stale-view issues.
Log filtering by user: in /var/log/odoo/odoo.log, filter by user ID to trace one user's session. Add (uid={uid}) pattern to the log format and grep for it.
EXPLAIN ANALYZE on slow queries: when you find a slow SQL query in the log, run it manually with EXPLAIN ANALYZE to see the query plan. Missing indexes show up as Sequential Scans on large tables.
pg_stat_statements: enable the Postgres extension to track query frequency and total time. Identifies the worst offenders across all sessions, not just one.
Server hibernation pattern: if your dev environment is on a laptop, the server sleeps when the laptop sleeps and the first RPC after wake takes 5+ seconds. Not actually a bug.
Browser cache poisoning: hard reload (Ctrl+Shift+R) skips the cache. Useful when troubleshooting "is this old code still cached?" issues.
Distinguishing client-side and server-side errors: server-side errors return JSON with error.data.debug (the traceback). Client-side errors show in the console with a JavaScript stack trace.
For complex performance optimization including multi-server load testing and database query tuning, ECOSIRE Odoo support provides full performance audits. Pair this with how to deploy Odoo on AWS EC2.
Frequently Asked Questions
What's the difference between ?debug=1 and ?debug=assets?
debug=1 enables developer features in the UI (technical menu, raw view editor) but keeps assets minified. debug=assets also disables minification so JS file names and line numbers are real. Use assets for client-side debugging. Use ?debug=tests to enable the test mode UI for running JS tests.
How do I debug RPC calls without browser access (e.g., a backend integration)?
Tail the access log: tail -f /var/log/nginx/access.log | grep call_kw. Or enable Odoo's request logging at INFO level. For deeper insight, instrument with structured logging that captures request_id, user, model, method, and timing.
Can I replay a session-based RPC?
Yes — copy the cookies from DevTools (Application > Cookies) into your tool of choice. Or use Postman with cookie persistence. The session cookie is session_id. For long-running debug sessions, generate a long-lived API key and use that instead.
Why does my custom xmlrpc/2/object call fail with 401?
XML-RPC uses different auth than the web session. You need to call authenticate first to get a uid, then pass it in subsequent calls. Different from JSON-RPC at /web/dataset/call_kw which uses session cookies.
How do I see SQL queries triggered by an RPC?
Set log_handler = :INFO,odoo.sql_db:DEBUG in odoo.conf and tail the log. Each query logs with timing. Useful for finding the N+1 query problem (one RPC triggering 100 SQL queries).
What does "DETACH PARTNER" mean in the log?
That's the WebSocket "longpolling" mechanism reconnecting. Not an error; it's the chat/notification subsystem keeping in touch with the server.
How do I trace a slow page load end-to-end?
Open DevTools > Performance > record. Refresh page. Stop. The flame graph shows JS time. The Network tab on the same recording shows server time. Total time = sum of network + JS rendering. Identify which dominates.
Can I edit an RPC response in DevTools and see how the UI reacts?
Yes — right-click the response > Override > Save. Edit the response. Refresh. Useful for testing UI behavior under unusual server responses without changing the server.
What about "Overhead" time in the Network tab?
That's TCP connection time + TLS handshake. For repeat requests on the same connection it's near zero. If you see it spiking, your client is connecting fresh each request — check keep-alive headers.
How do I recover from a corrupted JS bundle?
Hard-reload the page (Ctrl+Shift+R). If still broken, run odoo-bin -u web --stop-after-init to regenerate the asset bundle.
For full Odoo performance optimization including database query tuning and frontend asset bundling, ECOSIRE Odoo support handles end-to-end performance work. Or read how to write an Odoo unit test to lock in fixes with tests.
Rédigé par
ECOSIRE TeamTechnical Writing
The ECOSIRE technical writing team covers Odoo ERP, Shopify eCommerce, AI agents, Power BI analytics, GoHighLevel automation, and enterprise software best practices. Our guides help businesses make informed technology decisions.
ECOSIRE
Transformez votre entreprise avec Odoo ERP
Implémentation, personnalisation et assistance expertes d'Odoo pour rationaliser vos opérations.
Articles connexes
Comment ajouter un bouton personnalisé à une vue de formulaire Odoo (2026)
Ajoutez des boutons d'action personnalisés aux vues de formulaire Odoo 19 : méthode d'action Python, héritage des vues, visibilité conditionnelle, boîtes de dialogue de confirmation. Testé en production.
Comment ajouter un champ personnalisé dans Odoo sans Studio (2026)
Ajoutez des champs personnalisés via le module personnalisé dans Odoo 19 : héritage de modèle, extension de vue, champs calculés, décisions magasin/non-magasin. Code d'abord, contrôle de version.
Comment ajouter un rapport personnalisé dans Odoo à l'aide d'une mise en page externe
Créez un rapport PDF de marque dans Odoo 19 à l'aide de web.external_layout : modèle QWeb, format papier, liaison d'action. Avec logo imprimé + remplacements de pied de page.