phacility/phabricator · warning · PhutilArgumentUsageException
Object "%s" can not be destroyed (it does not implement %s).
Error message
Object "%s" can not be destroyed (it does not implement %s).
What it means
bin/remove destroy destroys objects through PhabricatorDestructibleInterface, which supplies destroyObjectPermanently() so the engine can clean up attached records. Objects that do not implement the interface have no destruction semantics and are refused before the confirmation banner.
Source
Thrown at src/applications/system/management/PhabricatorSystemRemoveDestroyWorkflow.php:49
}
$object_query = id(new PhabricatorObjectQuery())
->setViewer($this->getViewer())
->withNames($object_names);
$object_query->execute();
$named_objects = $object_query->getNamedResults();
foreach ($object_names as $object_name) {
if (empty($named_objects[$object_name])) {
throw new PhutilArgumentUsageException(
pht('No such object "%s" exists!', $object_name));
}
}
foreach ($named_objects as $object_name => $object) {
if (!($object instanceof PhabricatorDestructibleInterface)) {
throw new PhutilArgumentUsageException(
pht(
'Object "%s" can not be destroyed (it does not implement %s).',
$object_name,
'PhabricatorDestructibleInterface'));
}
}
$banner = <<<EOBANNER
uuuuuuu
uu###########uu
uu#################uu
u#####################u
u#######################u
u#########################u
u#########################u
u######" "###" "######u
"####" u#u ####"
###u u#u u###View on GitHub (pinned to 5720a38cfe)
Solutions
- Destroy the parent/container object instead; dependents are normally destroyed via its interface
- If this is your application, implement PhabricatorDestructibleInterface::destroyObjectPermanently() on the DAO and clean up dependent rows
- Use the application's own deletion workflow if it provides one
Example fix
// before: DAO has no destruction support (command refuses)
// after: implement the interface on your DAO
public function destroyObjectPermanently(
PhabricatorDestructionEngine $engine) {
$this->delete();
// also delete attached rows (e.g. file chunks, subscriptions)
} Defensive patterns
Strategy: type-guard
Type guard
function isDestructible($object) {
return ($object instanceof PhabricatorDestructibleInterface);
} Prevention
- Implement PhabricatorDestructibleInterface on custom objects that will be deletable
- Filter candidate object names through the interface check before calling destroy
- Destroy container objects rather than their dependents
When it happens
Trigger: Naming an object whose class does not implement PhabricatorDestructibleInterface: singleton/config-style rows, or objects that are only destroyed as a side effect of destroying some parent object.
Common situations: Trying to destroy raw configuration or custom DAO records where destruction semantics were never defined.
Related errors
- Specify one or more objects to destroy.
- No such object "%s" exists!
- Aborted, your objects are safe.
- Request parameter "%s" is not formatted properly. Expected a
- Request parameter "%s" is not formatted properly. Expected a
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/406d416be227630d.
Report an issue: GitHub.