Skip to content

Fix Odoo Custom Report Not Showing: QWeb Template, Action, and Rendering Issues

DeployMonkey Team · March 23, 2026 10 min read

The Missing Report Problem

You built a custom QWeb report, upgraded the module, but the report does not appear in the Print menu. Or it appears but renders blank. Or it throws a cryptic error when you try to generate the PDF. Custom reports in Odoo require several components working together, and a problem in any one of them breaks the entire report.

Report Architecture

A working Odoo report requires:

  1. ir.actions.report record — defines the report action, model binding, and output format
  2. QWeb template — the HTML template for the report content
  3. Paper format (optional) — page size, margins, orientation
  4. wkhtmltopdf — converts HTML to PDF

Problem 1: Report Not in Print Menu

# The report action exists but does not show in the Print menu

# Cause 1: binding_model_id not set
# The report must be bound to a model to appear in its Print menu

# Fix: Check the report action definition:
<record id="report_custom_invoice" model="ir.actions.report">
    <field name="name">Custom Invoice</field>
    <field name="model">account.move</field>
    <field name="report_type">qweb-pdf</field>
    <field name="report_name">my_module.report_custom_invoice_template</field>
    <!-- THIS IS REQUIRED for Print menu binding -->
    <field name="binding_model_id" ref="account.model_account_move"/>
    <field name="binding_type">report</field>
</record>

# Cause 2: Module not upgraded after adding the report
# Fix: Upgrade the module: -u my_module

# Cause 3: Report bound to wrong model
# A report bound to 'sale.order' won't appear on invoices
# Verify the model matches where you expect the Print button

Problem 2: Report Renders Blank PDF

# PDF downloads but all pages are blank

# Cause 1: wkhtmltopdf issue (see report URL timeout guide)
# Quick fix: Set report.url system parameter
# Settings → Technical → System Parameters
# Key: report.url  Value: http://127.0.0.1:8069

# Cause 2: Template name mismatch
# report_name in ir.actions.report must match template id
<!-- In report action: -->
<field name="report_name">my_module.report_template</field>

<!-- Template must have matching id: -->
<template id="report_template">
    <t t-call="web.html_container">
        <t t-foreach="docs" t-as="doc">
            <t t-call="web.external_layout">
                <div class="page">
                    <h1><t t-esc="doc.name"/></h1>
                </div>
            </t>
        </t>
    </t>
</template>

# Note: template id becomes my_module.report_template
# The report_name must be exactly this

Problem 3: Template Rendering Error

# Error in logs:
# ValueError: External ID not found: my_module.report_template
# Or: QWebException: 'NoneType' object has no attribute 'name'

# Cause 1: Template XML file not in __manifest__.py
# Fix: Add the template file to the 'data' list:
'data': [
    'reports/custom_report.xml',
],

# Cause 2: Field access error — doc.field_name doesn't exist
# Fix: Verify all field names in the template match the model
# Common: typos, accessing Many2one without .name, wrong field type

# Cause 3: Accessing a related field without checking for None
# BAD:
<t t-esc="doc.partner_id.commercial_partner_id.vat"/>
# If partner_id is empty, this crashes

# FIX:
<t t-if="doc.partner_id">
    <t t-esc="doc.partner_id.commercial_partner_id.vat"/>
</t>

Problem 4: Wrong Paper Format

# Report prints but layout is wrong — margins too big, content cut off

# Fix: Define and assign a paper format:
<record id="paperformat_custom" model="report.paperformat">
    <field name="name">Custom A4</field>
    <field name="format">A4</field>
    <field name="orientation">Portrait</field>
    <field name="margin_top">25</field>
    <field name="margin_bottom">20</field>
    <field name="margin_left">7</field>
    <field name="margin_right">7</field>
    <field name="header_spacing">20</field>
    <field name="dpi">90</field>
</record>

# Assign to report:
<record id="report_custom_invoice" model="ir.actions.report">
    <field name="paperformat_id" ref="paperformat_custom"/>
</record>

Problem 5: Header/Footer Not Showing

# Report content shows but no company header or footer

# Cause: Not using web.external_layout

# Fix: Wrap report content in external_layout:
<template id="report_template">
    <t t-call="web.html_container">
        <t t-foreach="docs" t-as="doc">
            <t t-call="web.external_layout">
                <div class="page">
                    <!-- Report content here -->
                </div>
            </t>
        </t>
    </t>
</template>

# web.external_layout adds the company header and footer
# web.html_container provides the base HTML structure

Problem 6: Report Works in HTML But Not PDF

# HTML preview (qweb-html) works, but PDF generation fails

# Test HTML version:
# Change report_type temporarily:
<field name="report_type">qweb-html</field>
# Generate the report → if HTML works, the issue is wkhtmltopdf

# Common wkhtmltopdf issues:
# 1. CSS not supported by wkhtmltopdf (flexbox, grid, modern CSS)
#    Fix: Use tables and floats for layout
# 2. External fonts not loading
#    Fix: Embed fonts or use web-safe fonts
# 3. Images not loading (relative URLs)
#    Fix: Use absolute URLs or base64-encoded images

Debugging Reports

# 1. Check if report action exists:
# Settings → Technical → Actions → Reports
# Search for your report name

# 2. Preview HTML version:
# Navigate to: /report/html/my_module.report_template/RECORD_ID
# This shows the HTML that wkhtmltopdf will convert

# 3. Check template exists:
# In Odoo shell:
env.ref('my_module.report_template')
# Should return the template record without error

# 4. Enable report debug logging:
./odoo-bin --log-handler=odoo.addons.base.models.ir_actions_report:DEBUG