Saltar al contenido principal

Odoo Kanban View no muestra tarjetas: cómo solucionarlo rápidamente

¿La vista kanban de Odoo muestra columnas pero no tarjetas el 18/17/19? Diagnostique plantillas, errores JS y campos group_by con solución de problemas completa en producción ahora.

E
ECOSIRE Research and Development Team
|4 de mayo de 20267 min de lectura1.2k Palabras|

Este artículo actualmente está disponible solo en inglés. La traducción estará disponible próximamente.

Your Odoo kanban view loads, the column headers are there, the column counts are correct, but no cards appear inside. The browser console may show a quiet:

Your Odoo kanban view loads, the column headers are there, the column counts are correct, but no cards appear inside. The browser console may show a quiet:

Uncaught TypeError: Cannot read properties of undefined (reading 'name')
    at templates_X.js:124

Or it may show nothing at all. The data is in the database, the SQL count is right, the cards just refuse to render. This applies to Odoo 17.0/18.0/19.0 — the kanban renderer is one of the most complex view types and one of the easiest to break.

Quick Fix

Open the browser DevTools, look at the JavaScript console, find the first error. The fix is almost always one of:

<!-- WRONG — assumes record.partner_id always has a value -->
<t t-esc="record.partner_id.value.name"/>

<!-- RIGHT — guard the chain -->
<t t-esc="record.partner_id.value &amp;&amp; record.partner_id.value.name"/>
<!-- or with new template syntax -->
<t t-out="record.partner_id.value?.name || ''"/>

A single template error in a single record kills the rendering of every card on the page in many Odoo versions.

Why This Happens

Odoo kanban views use OWL templates that render client-side. A template error throws on render, the renderer aborts, and no cards display. The five common causes:

  1. Field referenced in template not loaded. The kanban arch must declare every field used in <field name="...">. Missing declarations cause undefined reads at render.
  2. Null values in a chain. record.partner_id.value.name blows up when the partner is unset. Templates need null-safe access.
  3. Incorrect t-attf-class syntax. Odoo 17.0 changed some template attribute syntax; 18.0 introduced t-out instead of t-esc for some cases. Mixing styles confuses the renderer.
  4. Bad default_group_by — the action specifies group_by in context but the field does not exist. The kanban groups into "False" with all cards stuck there or hidden.
  5. JS asset bundle stale. A custom kanban widget compiled for one version runs against another, throws at registration time.

Step-by-Step Diagnosis

1. Open the JS console. F12, Console tab. Reproduce the kanban load. Read the first error.

2. Check the kanban arch.

SELECT arch_db FROM ir_ui_view WHERE id = <view_id>;

Find every record.<field> reference. Each must have a <field name="<field>"/> declaration earlier in the kanban arch.

3. Test data shape.

records = env['my.model'].search([], limit=5).read([
    'partner_id', 'state', 'priority',
])
print(records)

Look for False or [id, "name"] versus the structure your template expects.

4. Check default_group_by:

action = env.ref('my_module.action_my_kanban')
print(action.context)  # should contain valid group_by

If the context says 'group_by': 'stage_id' but stage_id does not exist on the model, every record falls into a "False" group.

5. Clear web assets.

DELETE FROM ir_attachment WHERE url LIKE '/web/assets/%';

Restart Odoo. If the kanban renders correctly now, your asset bundle was stale.

Permanent Fix

Declare every field used in the template:

<kanban>
    <field name="name"/>
    <field name="partner_id"/>      <!-- declare even if shown via record.partner_id -->
    <field name="amount_total"/>
    <field name="state"/>
    <field name="currency_id"/>     <!-- needed for monetary widget -->

    <templates>
        <t t-name="kanban-box">
            <div class="oe_kanban_card">
                <h3><t t-esc="record.name.value"/></h3>
                <div t-if="record.partner_id.value">
                    <t t-esc="record.partner_id.value[1]"/>
                </div>
                <div>
                    <field name="amount_total" widget="monetary"/>
                </div>
            </div>
        </t>
    </templates>
</kanban>

The <field name="..."/> declarations are how Odoo knows which fields to fetch. Missing one = undefined at render.

Use null-safe template syntax:

<!-- Odoo 17.0+ syntax with t-out and optional chaining -->
<t t-out="record.partner_id.value &amp;&amp; record.partner_id.value[1] || 'No customer'"/>
<t t-attf-class="oe_kanban_card #{record.state.raw_value === 'done' ? 'card-done' : ''}"/>

For default_group_by issues, validate the action's context:

<record id="action_my_kanban" model="ir.actions.act_window">
    <field name="name">My Records</field>
    <field name="res_model">my.model</field>
    <field name="view_mode">kanban,list,form</field>
    <field name="context">{'group_by': 'stage_id'}</field>   <!-- ensure stage_id exists -->
</record>

If stage_id is added by a custom module, depend on that module so the field is guaranteed.

For widget mismatches, register widgets correctly for the Odoo version. The widget registry changed locations between 17.0 and 18.0; check the official web/static/src/views/widgets/ for the current pattern.

How to Prevent It

  • Test on real data shape. Empty kanban renders fine; one record with a NULL partner_id exposes the template bug. Always test with at least three records and one record with optional fields unset.
  • Lint kanban arch. Walk the kanban XML, extract every record.<field> reference, ensure each has a matching <field name="<field>"/> declaration. ECOSIRE's Odoo customization team ships this lint with every kanban view.
  • Snapshot test the rendered HTML. A Playwright test that opens the kanban, asserts at least one card renders, catches regressions cheaply.
  • Use the t-out form for new kanban templates. It supports null-safe chaining natively in Odoo 18.0+.
  • Clear asset cache after every customization deploy. A cron-scheduled DELETE on /web/assets/% after deploys keeps the bundle fresh.
  • Avoid deeply nested record.field.value.subfield. Prefer storing a denormalized field on the model than walking 3-deep in a template.

Frequently Asked Questions

My kanban renders in admin but not for portal users. Why?

Almost always ACL — portal users do not have read access to one of the fields the template references, so the render aborts. Check the field declarations against the user's ir.model.access rights.

Can I debug a kanban template with the Odoo Developer Mode?

Yes. Developer Mode exposes "Edit KanbanView" which shows the composed arch. Open the JS console, look at odoo.session_info for the user, and inspect Component.env from a paused breakpoint inside the template renderer. For deeper debugging, the web_owl_devtools browser extension shows the OWL component tree.

Why does my custom kanban widget work in dev but not in production?

Asset bundling. Dev mode serves assets unbundled (one file per source); production bundles them with minification. A widget that registers via a side-effect can fire in the wrong order in the bundled context. Use the explicit registry.category('view_widgets').add('my_widget', MyWidget) pattern, which is order-safe.

Either guard in the template (record.partner_id.value &amp;&amp; ...) or make the field a stored compute that defaults to a sensible string ("No customer"). The compute pattern is more robust because every kanban for the model gets the right behaviour automatically.

Can I lazy-load images on a kanban with hundreds of cards?

Yes. Use <img loading="lazy"/> for native lazy load. For Odoo-stored images, the image widget supports a placeholder attribute. For very large kanbans, also set the action's context {'kanban_load_more': True} to enable virtualized rendering — only visible cards are rendered, scrolling loads more. Reduces initial render time by 80 percent on 500-card boards.

My drag-and-drop between kanban columns no longer works in Odoo 18.0

The drag handler was rewritten in 18.0 to use OWL's useService('drag'). Custom widgets that used the old Sortable import need migrating. The OCA web_kanban_smart_grouping ports several common drag patterns to the new API.

About 80 to 100 visible. Past that, the OWL renderer's reactive update tree gets expensive on every state change. Combine a default_group_by with a sensible domain to keep columns under 100. For workflows with more, switch to a list-view "smart pipeline" pattern.


Need help with a tricky Odoo error? ECOSIRE's Odoo experts have shipped 215+ modules — get expert help.

Compartir:
E

Escrito por

ECOSIRE Team

Technical 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

Transforme su negocio con Odoo ERP

Implementación, personalización y soporte experto de Odoo para optimizar sus operaciones.