Skip to content

Fix Odoo View Not Found After Upgrade: Invalid View Architecture and Broken Inheritance

DeployMonkey Team · March 23, 2026 10 min read

The View Not Found Problem

After upgrading a module or the Odoo version itself, views break. You see "Invalid View Architecture" errors, blank pages, or missing form/list views. This happens because view inheritance is fragile — if a parent view changes, child views that depend on specific XML structure can break.

Common Error Messages

# Error 1: View not found
ValueError: View not found: module.view_xml_id

# Error 2: Invalid view architecture
ValidationError: Invalid view definition
View inheritance may not use 'xpath' expressions referencing fields
that do not exist in the parent view.

# Error 3: Broken xpath
ValueError: Element '//field[@name="old_field"]' not found
in parent view 'module.parent_view_id'

# Error 4: Duplicate view key
IntegrityError: duplicate key value violates unique constraint
"ir_ui_view_key_unique"

Cause 1: Parent View Changed

The parent module changed its view structure, and your inherited view's xpath expressions no longer match.

# Your inherited view:
<record id="view_partner_form_inherit" model="ir.ui.view">
    <field name="inherit_id" ref="base.view_partner_form"/>
    <field name="arch" type="xml">
        <field name="old_field_name" position="after">
            <field name="my_custom_field"/>
        </field>
    </field>
</record>

# After Odoo upgrade, 'old_field_name' was renamed to 'new_field_name'
# Your xpath can't find the target → error

# Fix: Update your xpath to match the new parent view structure
<field name="new_field_name" position="after">
    <field name="my_custom_field"/>
</field>

Cause 2: Module Removed But Views Remain

# A module was uninstalled but its views remain in the database
# (noupdate=1 records don't get removed)

# Fix: Find and delete orphaned views
# In Odoo shell:
broken_views = env['ir.ui.view'].search([
    ('inherit_id', '!=', False),
    ('inherit_id.exists', '=', False)
])
for v in broken_views:
    print(f'Orphan: {v.name} (module: {v.key})')
# broken_views.unlink()  # Delete them

# Via SQL — find views referencing non-existent parents:
SELECT v.id, v.name, v.key, v.inherit_id
FROM ir_ui_view v
LEFT JOIN ir_ui_view parent ON v.inherit_id = parent.id
WHERE v.inherit_id IS NOT NULL AND parent.id IS NULL;

Cause 3: XML Syntax Error in View

# A syntax error in the view XML prevents it from loading

# Common XML errors:
# - Unclosed tags: <field name="x"> without </field>
# - Unescaped ampersands: "A & B" should be "A &amp; B"
# - Wrong attribute syntax: position=after (missing quotes)
# - Invalid characters in field names

# Fix: Validate your XML file:
xmllint --noout your_view_file.xml

# Or check in Python:
from lxml import etree
tree = etree.parse('your_view_file.xml')  # Throws if invalid

Cause 4: View Priority Conflict

# Two views inherit the same parent and modify the same element
# The execution order depends on priority (sequence)

# Fix: Set explicit priority on your inherited views:
<record id="my_view_inherit" model="ir.ui.view">
    <field name="inherit_id" ref="base.view_partner_form"/>
    <field name="priority" eval="99"/>  <!-- Higher = later -->
    <field name="arch" type="xml">
        ...
    </field>
</record>

# Default priority is 16. Lower numbers load first.
# If your view depends on another module's view change,
# set a higher priority to ensure it loads after.

Cause 5: Stale View Cache

# Odoo caches compiled views. Stale cache can show old/broken views

# Fix 1: Clear view cache
./odoo-bin -d mydb -u base --stop-after-init
# Upgrading 'base' forces all view recompilation

# Fix 2: Restart with --dev=xml
./odoo-bin --dev=xml  # Reloads XML on every request

# Fix 3: Invalidate cache in shell
env['ir.ui.view'].clear_caches()
env.cr.commit()

Cause 6: QWeb Template Not Found

# QWeb templates (used in website, reports, kanban) have separate errors

# Error: QWebException: Template 'module.template_name' not found

# Fix: Check template exists:
env.ref('module.template_name', raise_if_not_found=False)

# If missing, check:
# 1. Template file listed in __manifest__.py data section
# 2. XML file has correct template syntax:
<template id="template_name">
    <div>Content</div>
</template>
# 3. Module has been upgraded after adding the template

Emergency View Repair

# When you can't access Odoo at all because of a broken view:

# Option 1: Disable the problematic view
psql -d mydb -c "
    UPDATE ir_ui_view SET active = FALSE
    WHERE key = 'my_module.broken_view_id';
"
# Restart Odoo

# Option 2: Reset the view to its default
# Delete the broken view — Odoo recreates it on upgrade
psql -d mydb -c "
    DELETE FROM ir_ui_view WHERE key = 'my_module.broken_view_id';
"
./odoo-bin -d mydb -u my_module --stop-after-init

# Option 3: Fix the view XML directly
psql -d mydb -c "
    SELECT id, arch_db FROM ir_ui_view
    WHERE key = 'my_module.broken_view_id';
"
# Edit the arch_db content to fix the XML
# Then restart Odoo

# Option 4: Start Odoo with --no-update to bypass view validation
# (Not available in all versions)

Prevention

  • Use robust xpath expressions that survive parent changes — target unique attributes or groups
  • Always test module upgrades on a database copy first
  • Keep custom modules compatible with the target Odoo version
  • Use position="inside" instead of position="replace" when possible — it is more resilient
  • Pin your Odoo version and upgrade deliberately, not automatically