{"record":{"id":"fc2735511e405dba","repo":"doctrine/orm","slug":"unexpected-entity-state-s-s","errorCode":null,"errorMessage":"Unexpected entity state: %s. %s","messagePattern":"Unexpected entity state: (.+?)\\. (.+?)","errorType":"exception","errorClass":"UnexpectedValueException","httpStatus":null,"severity":"error","filePath":"src/UnitOfWork.php","lineNumber":1849,"sourceCode":"            case self::STATE_REMOVED:\n                // Entity becomes managed again\n                unset($this->entityDeletions[$oid]);\n                $this->addToIdentityMap($entity);\n\n                $this->entityStates[$oid] = self::STATE_MANAGED;\n\n                if ($class->isChangeTrackingDeferredExplicit()) {\n                    $this->scheduleForDirtyCheck($entity);\n                }\n\n                break;\n\n            case self::STATE_DETACHED:\n                // Can actually not happen right now since we assume STATE_NEW.\n                throw ORMInvalidArgumentException::detachedEntityCannot($entity, 'persisted');\n\n            default:\n                throw new UnexpectedValueException(sprintf(\n                    'Unexpected entity state: %s. %s',\n                    $entityState,\n                    self::objToStr($entity),\n                ));\n        }\n\n        $this->cascadePersist($entity, $visited);\n    }\n\n    /**\n     * Deletes an entity as part of the current unit of work.\n     */\n    public function remove(object $entity): void\n    {\n        $visited = [];\n\n        $this->doRemove($entity, $visited);\n    }","sourceCodeStart":1831,"sourceCodeEnd":1867,"githubUrl":"https://github.com/doctrine/orm/blob/d9b9ff73016bf598ae07515f97289ce8074e97a5/src/UnitOfWork.php#L1831-L1867","documentation":"UnitOfWork::doPersist switches over the entity's computed state (STATE_MANAGED, STATE_NEW, STATE_REMOVED each have explicit handling, STATE_DETACHED throws a dedicated exception). This default arm fires only when the state value falls outside all known constants - an internal invariant break rather than a user input problem. The message includes the numeric state and a string representation of the entity for diagnosis.","triggerScenarios":"$em->persist($entity) when UnitOfWork::getEntityState() yields an unexpected value: custom UnitOfWork subclasses or reflection tampering with internal state maps, an EntityManager corrupted by serialization/cloning of internal objects, or doctrine/orm classes from two different versions loaded in the same process.","commonSituations":"Essentially never in normal usage; seen with duplicated composer dependencies/phar classmaps loading mixed ORM versions, extensions subclassing UnitOfWork internals, or diagnostics tooling serializing the EntityManager.","solutions":["Check $uow->getEntityState($entity) before persisting and handle non-standard/detached states explicitly (e.g. merge or reload instead of persist).","Verify only one version of doctrine/orm is loaded: composer show doctrine/orm and check for duplicate vendor copies or phar bundling.","Remove code that subclasses or reflects into UnitOfWork internals, or that serializes/clones the EntityManager."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate the state is one Doctrine handles before persisting\n$state = $em->getUnitOfWork()->getEntityState($entity);\nif (! in_array($state, [UnitOfWork::STATE_NEW, UnitOfWork::STATE_MANAGED, UnitOfWork::STATE_REMOVED], true)) {\n    throw new InvalidArgumentException('Cannot persist entity in state ' . $state); // includes DETACHED: merge/find first\n}\n$em->persist($entity);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never serialize or clone an EntityManager/UnitOfWork","Keep exactly one doctrine/orm version in the dependency tree (composer show doctrine/orm)","Do not subclass or reflect into UnitOfWork internals"],"tags":["doctrine-orm","unit-of-work","entity-state","persist","internal-invariant"],"backgroundTag":"orm-invalid-entity-state","analyzedSha":"d9b9ff73016bf598ae07515f97289ce8074e97a5","analyzedAt":"2026-08-21T06:13:15.863Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}