{"record":{"id":"26e63564c8c1e54e","repo":"cakephp/cakephp","slug":"could-not-find-primary-key-value-for-source-entity","errorCode":null,"errorMessage":"Could not find primary key value for source entity","messagePattern":"Could not find primary key value for source entity","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/ORM/Association/BelongsToMany.php","lineNumber":1215,"sourceCode":"     * `$article->get('tags')` will contain only `[$tag1, $tag3]` at the end\n     *\n     * @param \\Cake\\Datasource\\EntityInterface $sourceEntity an entity persisted in the source table for\n     *   this association\n     * @param array $targetEntities list of entities from the target table to be linked\n     * @param array<string, mixed> $options list of options to be passed to the internal `save`/`delete` calls\n     *   when persisting/updating new links, or deleting existing ones\n     * @throws \\InvalidArgumentException if non persisted entities are passed or if\n     *   any of them is lacking a primary key value\n     * @return bool success\n     */\n    public function replaceLinks(EntityInterface $sourceEntity, array $targetEntities, array $options = []): bool\n    {\n        $bindingKey = (array)$this->getBindingKey();\n        $primaryValue = $sourceEntity->extract($bindingKey);\n\n        if (count(Hash::filter($primaryValue)) !== count($bindingKey)) {\n            $message = 'Could not find primary key value for source entity';\n            throw new InvalidArgumentException($message);\n        }\n\n        return $this->junction()->getConnection()->transactional(\n            function () use ($sourceEntity, $targetEntities, $primaryValue, $options) {\n                $junction = $this->junction();\n                $target = $this->getTarget();\n\n                /** @var array<string> $foreignKey */\n                $foreignKey = (array)$this->getForeignKey();\n                $assocForeignKey = (array)$junction->getAssociation($target->getAlias())->getForeignKey();\n                $prefixedForeignKey = array_map($junction->aliasField(...), $foreignKey);\n\n                $junctionPrimaryKey = (array)$junction->getPrimaryKey();\n                $junctionQueryAlias = $junction->getAlias() . '__matches';\n                $keys = [];\n                $matchesConditions = [];\n                /** @var string $key */\n                foreach (array_merge($assocForeignKey, $junctionPrimaryKey) as $key) {","sourceCodeStart":1197,"sourceCodeEnd":1233,"githubUrl":"https://github.com/cakephp/cakephp/blob/1128eba9b09f1946df684811350e26f2cef68fac/src/ORM/Association/BelongsToMany.php#L1197-L1233","documentation":"replaceLinks() rewrites the junction-table links for a saved source entity, which requires the entity's binding key values. If extracting the binding key columns from the source entity yields empty/null values, the links cannot be identified and this error is thrown.","triggerScenarios":"Calling $articles->Tags->replaceLinks($entity, $targets) where $entity is new or lacks the bindingKey properties (e.g. composite binding key only partially set).","commonSituations":"Calling replaceLinks on an unpersisted entity; entity was created with newEntity() without an id; composite primary key entity saved without all key columns.","solutions":["Persist (save) the source entity before calling replaceLinks so its primary/binding keys are populated","Verify the entity contains the binding key fields (check getBindingKey() against the entity)","Fix the bindingKey configuration on the association if it names wrong columns"],"exampleFix":"// before\n$article = $this->Articles->newEntity($data);\n$this->Articles->Tags->replaceLinks($article, $tags);\n// after\n$article = $this->Articles->save($this->Articles->patchEntity($this->Articles->newEmptyEntity(), $data));\n$this->Articles->Tags->replaceLinks($article, $tags);","handlingStrategy":"validation","validationCode":"$bindingKey = (array)$articles->Tags->getBindingKey();\nif (count(array_filter($entity->extract($bindingKey))) !== count($bindingKey)) {\n    $entity = $articles->save($entity); // or refetch\n}","typeGuard":null,"tryCatchPattern":"try { $assoc->replaceLinks($entity, $targets); } catch (InvalidArgumentException $e) { $entity = $assoc->getSource()->save($entity); $assoc->replaceLinks($entity, $targets); }","preventionTips":["Only call replaceLinks on persisted entities","Confirm bindingKey fields exist on the entity","Check ->isNew() before replaceLinks"],"tags":["cakephp","orm","belongs-to-many","primary-key"],"backgroundTag":"empty-required-field","analyzedSha":"1128eba9b09f1946df684811350e26f2cef68fac","analyzedAt":"2026-09-12T12:07:00.388Z","contentChangedAt":"2026-09-12T12:07:00.388Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}