{"record":{"id":"13a6eb5613430e38","repo":"PHPOffice/PHPWord","slug":"cannot-set-a-comment-on-a-comment","errorCode":null,"errorMessage":"Cannot set a Comment on a Comment","messagePattern":"Cannot set a Comment on a Comment","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/PhpWord/Element/AbstractElement.php","lineNumber":317,"sourceCode":"    /**\n     * Get comment start.\n     */\n    public function getCommentRangeStart(): ?Comment\n    {\n        if ($this->commentsRangeStart != null) {\n            return $this->commentsRangeStart->getItem($this->commentsRangeStart->countItems());\n        }\n\n        return null;\n    }\n\n    /**\n     * Set comment start.\n     */\n    public function setCommentRangeStart(Comment $value): void\n    {\n        if ($this instanceof Comment) {\n            throw new InvalidArgumentException('Cannot set a Comment on a Comment');\n        }\n        if ($this->commentsRangeStart == null) {\n            $this->commentsRangeStart = new Comments();\n        }\n        // Set ID early to avoid duplicates.\n        if ($value->getElementId() == null) {\n            $value->setElementId();\n        }\n        foreach ($this->commentsRangeStart->getItems() as $comment) {\n            if ($value->getElementId() == $comment->getElementId()) {\n                return;\n            }\n        }\n        $idxItem = $this->commentsRangeStart->addItem($value);\n        $this->commentsRangeStart->getItem($idxItem)->setStartElement($this);\n    }\n\n    /**","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/PHPOffice/PHPWord/blob/aef95c04151b5633cc505f672ddd6a71da900ee1/src/PhpWord/Element/AbstractElement.php#L299-L335","documentation":"AbstractElement::setCommentRangeStart() throws an InvalidArgumentException when the element receiving the comment range start is itself a Comment, since comments cannot contain comment ranges. This prevents self-referential comment structures that would produce invalid OOXML.","triggerScenarios":"Calling setCommentRangeStart($comment) on a Comment instance — e.g. chaining comment setup code that applies to all elements indiscriminately, or accidentally assigning the comment's own range markers onto another comment object.","commonSituations":"Iterating over all document elements and attaching comment ranges to each without excluding Comment instances; nested comment workflows; copy-pasted comment-attachment code applied to the comment object itself.","solutions":["Skip Comment instances before calling setCommentRangeStart (check with instanceof)","Attach comment ranges only to content elements like Text, TextRun, or Table","Guard with if (!$element instanceof Comment)"],"exampleFix":"// before\n$element->setCommentRangeStart($comment); // element may be a Comment\n// after\nif (!$element instanceof \\PhpOffice\\PhpWord\\Element\\Comment) {\n    $element->setCommentRangeStart($comment);\n}","handlingStrategy":"type-guard","validationCode":"if ($element instanceof \\PhpOffice\\PhpWord\\Element\\Comment) {\n    return; // cannot attach comment ranges to comments\n}","typeGuard":"function canCarryCommentRange($element): bool {\n    return !$element instanceof \\PhpOffice\\PhpWord\\Element\\Comment;\n}","tryCatchPattern":"try {\n    $element->setCommentRangeStart($comment);\n} catch (\\InvalidArgumentException $e) {\n    // skip comments; optionally log\n}","preventionTips":["Filter Comment instances out of element collections before attaching ranges","Use the same instanceof guard for setCommentRangeStart and setCommentRangeEnd","Centralize comment attachment in one helper that performs the guard"],"tags":["php","phpword","comment","invalid-argument"],"backgroundTag":"unsupported-operation","analyzedSha":"aef95c04151b5633cc505f672ddd6a71da900ee1","analyzedAt":"2026-09-14T10:53:58.933Z","contentChangedAt":"2026-09-14T10:53:58.933Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}