phacility/phabricator · error · Exception
Object ("%s") does not implement interface "%s", so this typ
Error message
Object ("%s") does not implement interface "%s", so this type of object can not be unlocked. What it means
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.
Source
Thrown at src/applications/system/engine/PhabricatorUnlockEngine.php:8
<?php
abstract class PhabricatorUnlockEngine
extends Phobject {
final public static function newUnlockEngineForObject($object) {
if (!($object instanceof PhabricatorApplicationTransactionInterface)) {
throw new Exception(
pht(
'Object ("%s") does not implement interface "%s", so this type '.
'of object can not be unlocked.',
phutil_describe_type($object),
'PhabricatorApplicationTransactionInterface'));
}
if ($object instanceof PhabricatorUnlockableInterface) {
$engine = $object->newUnlockEngine();
} else {
$engine = new PhabricatorDefaultUnlockEngine();
}
return $engine;
}
public function newUnlockViewTransactions($object, $user) {
$type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;View on GitHub (pinned to 5720a38cfe)
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
Example fix
// before
$engine = PhabricatorUnlockEngine::newUnlockEngineForObject($object);
// after: guard the interface requirement first
if (!($object instanceof PhabricatorApplicationTransactionInterface)) {
throw new Exception(pht('This object type can not be unlocked.'));
}
$engine = PhabricatorUnlockEngine::newUnlockEngineForObject($object); Defensive patterns
Strategy: type-guard
Type guard
function canUnlockObject($object) {
return ($object instanceof PhabricatorApplicationTransactionInterface);
} Try / catch
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.
Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Object view policy can not be unlocked because this object d
- Object edit policy can not be unlocked because this object d
- Object owner can not be unlocked: the unlocking engine ("%s"
- Unrecognized verb: %s
- This object ("%s") has more than %s transactions in its most
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/08ac40cc94c8edc5.
Report an issue: GitHub.