{"record":{"id":"08ac40cc94c8edc5","repo":"phacility/phabricator","slug":"object-s-does-not-implement-interface-s-s","errorCode":null,"errorMessage":"Object (\"%s\") does not implement interface \"%s\", so this type of object can not be unlocked.","messagePattern":"Object \\(\"(.+?)\"\\) does not implement interface \"(.+?)\", so this type of object can not be unlocked\\.","errorType":"console","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/applications/system/engine/PhabricatorUnlockEngine.php","lineNumber":8,"sourceCode":"<?php\n\nabstract class PhabricatorUnlockEngine\n  extends Phobject {\n\n  final public static function newUnlockEngineForObject($object) {\n    if (!($object instanceof PhabricatorApplicationTransactionInterface)) {\n      throw new Exception(\n        pht(\n          'Object (\"%s\") does not implement interface \"%s\", so this type '.\n          'of object can not be unlocked.',\n          phutil_describe_type($object),\n          'PhabricatorApplicationTransactionInterface'));\n    }\n\n    if ($object instanceof PhabricatorUnlockableInterface) {\n      $engine = $object->newUnlockEngine();\n    } else {\n      $engine = new PhabricatorDefaultUnlockEngine();\n    }\n\n    return $engine;\n  }\n\n  public function newUnlockViewTransactions($object, $user) {\n    $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/applications/system/engine/PhabricatorUnlockEngine.php#L1-L26","documentation":"PhabricatorUnlockEngine::newUnlockEngineForObject() requires the object to implement PhabricatorApplicationTransactionInterface, because unlocking is implemented by applying application transactions (view/edit policy changes). Objects that do not participate in the application-transactions framework cannot be unlocked, and this Exception rejects them before any engine is selected.","triggerScenarios":"Calling PhabricatorUnlockEngine::newUnlockEngineForObject($object) directly or via the unlock workflow with an object that is not a PhabricatorApplicationTransactionInterface implementer: a raw DAO row, an exotic object type, or a custom application whose storage never adopted transactions.","commonSituations":"Administrators attempting to unlock an unusual object type through generic tooling; custom applications missing the transaction interface; generic admin scripts passing a loaded object of the wrong class.","solutions":["Check instanceof PhabricatorApplicationTransactionInterface before invoking the unlock engine and skip unsupported types with a clear message","Use the object type's own administrative recovery workflow instead of the generic unlock engine","If it is your custom application, implement PhabricatorApplicationTransactionInterface and an application editor on the DAO so unlocks become transaction-based"],"exampleFix":"// before\n$engine = PhabricatorUnlockEngine::newUnlockEngineForObject($object);\n\n// after: guard the interface requirement first\nif (!($object instanceof PhabricatorApplicationTransactionInterface)) {\n  throw new Exception(pht('This object type can not be unlocked.'));\n}\n$engine = PhabricatorUnlockEngine::newUnlockEngineForObject($object);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function canUnlockObject($object) {\n  return ($object instanceof PhabricatorApplicationTransactionInterface);\n}","tryCatchPattern":"Catch Exception around newUnlockEngineForObject() only to convert it into a friendly 'this object type cannot be unlocked' message; treat it as a permanent, non-retryable condition.","preventionTips":["Gate unlock UI actions on the instanceof check before invoking the engine","Keep a whitelist of unlockable object types in admin tooling","Implement PhabricatorApplicationTransactionInterface on custom DAOs that need unlock support"],"tags":["unlock","admin","interface-check","policies","transactions"],"backgroundTag":"interface-not-implemented","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}