Comment corriger DELETE_FAILED dans les déploiements Salesforce

La suppression d'un enregistrement est bloquée par une relation de lookup, un trigger ou une approbation en attente, distinct du DEPENDENCY_EXISTS au niveau des métadonnées.

Se produit pendant : les suppressions DML à l'exécution, lors des chargements de données, des jobs batch et des tests Apex

Ce que cela signifie

DELETE_FAILED est une erreur au niveau des données renvoyée lorsqu'une opération de suppression DML ne peut pas aboutir, généralement parce qu'un autre enregistrement détient encore une référence lookup ou master-detail vers lui, qu'un trigger a bloqué la suppression, ou que l'enregistrement est verrouillé par une approbation en attente. Elle s'applique aux suppressions d'enregistrements lors des chargements de données et des tests Apex, pas à la suppression de composants de métadonnées.

Les enfants master-detail sont supprimés automatiquement quand le parent est supprimé, donc cette erreur concerne presque toujours une relation de lookup, où Salesforce laisse le choix entre cascade ou blocage à la configuration du champ, ou une logique personnalisée qui empêche explicitement la suppression.

Diagnostic

Causes courantes

Des enregistrements enfants référencent encore l'enregistrement via un lookup
Un champ de lookup sur un autre objet pointe vers l'enregistrement à supprimer, et la relation n'est pas configurée pour cascader ou s'effacer automatiquement.
Un trigger ou une règle de validation bloque la suppression
Un Apex personnalisé ou une règle de validation sur l'objet empêche explicitement la suppression sous certaines conditions, comme une vérification de statut.
L'enregistrement est verrouillé par un processus d'approbation
L'enregistrement est en cours d'approbation, et Salesforce ne vous laissera pas le supprimer entre-temps.

La solution

  1. Supprimez ou reliez d'abord les enregistrements enfants
    Supprimez ou mettez à jour le lookup sur les enregistrements dépendants avant de supprimer le parent, ou configurez le champ pour qu'il s'efface à la suppression si c'est le comportement souhaité.
  2. Vérifiez la logique des triggers et des règles de validation
    Recherchez une logique bloquant la suppression dans les triggers Apex (trigger.isDelete) et les règles de validation qui se déclenchent à la suppression.
  3. Annulez ou finalisez les approbations en attente
    Résolvez tout processus d'approbation en cours sur l'enregistrement avant de tenter la suppression.
En pratique

Comment Serpent évite cela

Les contrôles préalables de Serpent signalent les enregistrements et les métadonnées dépendantes que les changements de données d'une tâche affecteraient, de sorte qu'une suppression bloquée apparaît avant une release au lieu d'échouer en cours de déploiement. Consultez la bibliothèque des erreurs de déploiement Salesforce.

Constructeur de pipelines CI/CD no-code dans Serpent

Prévention

Décidez du comportement de cascade dès la conception du champ
Choisissez délibérément entre « Effacer la valeur de ce champ » et « Ne pas autoriser la suppression » lors de la création d'un lookup, plutôt que de découvrir le comportement par défaut lors d'une suppression en masse.
Entourez les suppressions en batch d'une pré-vérification des dépendances
Recherchez les enregistrements enfants et les approbations en attente avant l'exécution d'un job de suppression en masse, et ignorez ou signalez les parents bloqués plutôt que de laisser tout le batch échouer.
Documentez les triggers bloquant la suppression quand ce n'est pas évident
Commentez tout trigger qui met son veto à une suppression selon un statut ou une règle métier, afin que les futurs nettoyages de données ne tombent pas dessus à l'aveugle.
Questions fréquentes

DELETE_FAILED, expliqué

DELETE_FAILED est-il la même erreur que DEPENDENCY_EXISTS ?
Non. DEPENDENCY_EXISTS bloque la suppression de métadonnées, comme un champ ou un objet, parce que d'autres métadonnées les référencent. DELETE_FAILED bloque la suppression d'un enregistrement de données parce que d'autres enregistrements ou automatisations le référencent.
Pourquoi la suppression du parent fonctionne-t-elle parfois mais pas toujours sur le même lookup ?
Le comportement de suppression du champ de lookup est défini par champ, pas automatique. S'il est configuré pour effacer la valeur à la suppression, le parent se supprime sans problème ; s'il est configuré pour restreindre la suppression, toute référence enfant la bloque.
Le déplacement de l'enregistrement dans la corbeille compte-t-il comme une suppression pour cette vérification ?
Oui, une suppression douce (soft delete) vers la corbeille déclenche toujours les mêmes vérifications de dépendance et de trigger qu'une suppression définitive ; l'enregistrement n'a réellement disparu qu'une fois la corbeille vidée, mais la vérification DELETE_FAILED s'exécute dès l'étape de suppression douce.

Démarrez gratuitement. Pas de carte bancaire, pas d'installation, pas d'engagement.

Configuration en moins de 15 minutes. Aucun recrutement DevOps nécessaire.

Curieux de livrer plus vite avant de vous lancer ? Parlons-en

Sans engagement.