Se rendre au contenu

Corriger l’erreur “ValueError: Expected Singleton” dans Odoo

Comprenez et corrigez l’erreur « expected singleton » dans Odoo grâce à des explications limpides, aux causes les plus fréquentes et à des solutions pas-à-pas destinées aux utilisateurs et développeurs Odoo.
17 février 2026 par
Elisa Van Outrive
| Aucun commentaire pour l'instant

Introduction


Si vous avez déjà personnalisé Odoo ou développé des modules, il y a de fortes chances que vous ayez déjà croisé ce message déroutant.


ValueError: Expected singleton

Cette exception revient souvent lorsqu’une méthode attend de travailler sur un seul enregistrement, mais qu’elle reçoit un ensemble (recordset) contenant plusieurs éléments. Derrière le libellé technique se cache généralement une incompréhension du fonctionnement des recordsets dans l’ORM d’Odoo.


Ce guide démystifie l’erreur « Expected Singleton » : ce qu’elle signifie, d’où elle provient et comment la corriger sans casser la logique métier ni les interfaces connectées.

Que signifie « Expected Singleton » dans Odoo ?


L’ORM d’Odoo ne manipule pas des objets isolés par défaut, mais des recordsets — ensembles dynamiques d’enregistrements qui peuvent correspondre à plusieurs cas :

  • Un seul enregistrement
  • Plusieurs enregistrements
  • Aucun enregistrement

Quand une méthode conçue pour un seul enregistrement reçoit en réalité plusieurs éléments dans le recordset, Odoo lève l’exception susmentionnée.


ValueError: Expected singleton

Pour le dire plus simplement :

Odoo attendait un unique enregistrement. Il en a reçu plusieurs.

Vous rencontrerez généralement cette erreur dans les contextes suivants :

  • Les journaux serveur (logs)
  • Les méthodes de modules personnalisés
  • Les champs calculés (computed fields)
  • Les actions déclenchées par bouton
  • Les actions automatisées (automated actions)
  • Les opérations en masse (bulk updates)

La clé pour résoudre proprement le problème est de bien comprendre le comportement des recordsets.



Pourquoi cette erreur survient-elle


 

1. Mauvaise compréhension des recordsets


Dans Odoo, self est, la plupart du temps, un recordset et non un objet unique.

Même si vous pensez manipuler un seul élément, Odoo peut appeler votre méthode avec plusieurs enregistrements lors de :

  • Opérations en lot depuis la vue liste (tree view)
  • Workflows automatisés
  • Actions serveur
  • Importations via API

Si votre code suppose qu’il n’y a qu’un seul enregistrement, il finira par casser.


2. Oublier de boucler dans la méthode


Exemple d’un comportement problématique :

def action_confirm(self): self.state = 'confirmed'

Si self regroupe plusieurs enregistrements, l’affectation est ambiguë et provoque l’erreur.


Approche correcte :


def action_confirm(self): for record in self: record.state = 'confirmed'

3. Mauvaise utilisation de ensure_one()


Odoo propose un outil pour imposer l’unicité :


self.ensure_one()

Cette méthode force l’exécution uniquement si le recordset contient exactement un enregistrement ; sinon elle lève volontairement l’erreur singleton.


N’utilisez ensure_one() que lorsque la logique métier exige strictement un seul enregistrement (par exemple l’ouverture d’un formulaire spécifique).


4. Recherches retournant plusieurs enregistrements


Exemple courant :


partner = self.env['res.partner'].search([('name', '=', 'John')])

Si plusieurs partenaires s’appellent “John” et que la suite du code attend un unique résultat, l’erreur se déclenche.


Alternative sécurisée :


partner = self.env['res.partner'].search([('name', '=', 'John')], limit=1)

5. Ambiguïté sur les champs relationnels


Les problèmes surviennent souvent autour des relations Many2one ou One2many.


Exemple courant :


Considérons : self.order_line.product_id.name

Si order_line contient plusieurs lignes, l’expression devient ambiguë et peut provoquer l’erreur.

Comment corriger l’erreur Expected Singleton


 

Étape 1 – Itérer sur les recordsets


Règle de base :


Considérez toujours que self peut contenir plusieurs enregistrements.

for record in self: record.process_logic()

Étape 2 – Utiliser limit=1 quand c’est pertinent


Quand seul un enregistrement a du sens dans le contexte :


record = self.env['model.name'].search(domain, limit=1)

Étape 3 – Valider les champs relationnels


Vérifiez systématiquement :


  • Les relations Many2one (un vers un)
  • Les collections One2many (un vers plusieurs)
  • Les filtres de domaines appliqués

Assurez-vous de ne pas travailler, sans le savoir, sur plusieurs lignes.


Étape 4 – Revoir les processus d’API et d’import


Dans les environnements intégrés, les opérations en masse déclenchent souvent cette erreur parce que plusieurs enregistrements sont traités simultanément.


Si Odoo synchronise des données depuis des systèmes externes, concevez des méthodes sûres pour le traitement par lots.

Comment éviter cette erreur dans le développement Odoo



  • Évitez de supposer un contexte à enregistrement unique
  • Testez les méthodes avec plusieurs enregistrements sélectionnés
  • Privilégiez les boucles par défaut
  • Ajoutez limit=1 consciemment lorsque nécessaire
  • Structurez proprement les champs relationnels

Dans des architectures complexes d’intégration, ce type d’erreur apparaît souvent lors d’imports automatisés ou de tâches planifiées. Penser ‘batch-safe’ évite des instabilités en production.

Comment Dasolo gère les erreurs liées aux recordsets et à l’ORM


L’erreur « Expected Singleton » n’est pas toujours une simple faute de code : elle met souvent en lumière des présupposés profonds sur le comportement des recordsets, l’utilisation de l’ORM et la cohérence des flux de données.


Chez Dasolo, nous traitons ces erreurs en analysant la manière dont les recordsets sont manipulés tout au long du cycle de vie du module. Les problèmes de singleton surviennent fréquemment lorsque la logique métier est prévue pour un enregistrement unique mais est exécutée sur des ensembles multiples — notamment dans les workflows automatisés, les intégrations et les champs calculés.


Pour éviter la réapparition des exceptions singleton, nous mettons l’accent sur :


  • Des schémas d’itération explicites sur les recordsets
  • Une utilisation réfléchie et limitée de ensure_one()
  • Des filtres de domaine prévisibles et robustes
  • Une architecture relationnelle claire
  • Un contrôle strict des déclencheurs automatisés

Penser l’ORM pour l’évolutivité réduit significativement les erreurs inattendues en production.



Conclusion


En résumé, l’erreur « Expected Singleton » signale que du code tente d’opérer sur plusieurs enregistrements alors qu’il n’en attendait qu’un. Si elle ressemble à une erreur de débutant, elle révèle souvent des incohérences dans la gestion des recordsets ou des processus automatisés.


Comprendre le modèle de recordsets d’Odoo et appliquer des patterns sûrs d’itération permet d’éviter ce type d’erreurs. Des validations explicites, un filtrage maîtrisé et une logique d’automatisation contrôlée sont essentiels pour garder des déploiements Odoo stables et prévisibles.


Bien traitée, une exception singleton devient un indicateur utile : elle aide à renforcer la qualité du code et la fiabilité du système sur le long terme.

Questions fréquentes


Non. Elle existe sur Odoo 14, 15, 16 et 17.

Non. Il s’agit d’un problème logique dans la manière dont les enregistrements sont manipulés.

Non. Utilisez ensure_one() uniquement quand la logique métier exige absolument l’exécution sur un seul enregistrement.


Elisa Van Outrive 17 février 2026
Partager cet article
Se connecter pour laisser un commentaire.