{"record":{"id":"a16240bc07a2a807","repo":"PHPOffice/PHPWord","slug":"can-not-clone-row-template-variable-not-found-or-variable","errorCode":null,"errorMessage":"Can not clone row, template variable not found or variable contains markup.","messagePattern":"Can not clone row, template variable not found or variable contains markup\\.","errorType":"exception","errorClass":"PhpOffice\\PhpWord\\Exception\\Exception","httpStatus":null,"severity":"error","filePath":"src/PhpWord/TemplateProcessor.php","lineNumber":768,"sourceCode":"     */\n    public function getVariables()\n    {\n        return array_keys($this->getVariableCount());\n    }\n\n    /**\n     * Clone a table row in a template document.\n     *\n     * @param string $search\n     * @param int $numberOfClones\n     */\n    public function cloneRow($search, $numberOfClones): void\n    {\n        $search = static::ensureMacroCompleted($search);\n\n        $tagPos = strpos($this->tempDocumentMainPart, $search);\n        if (!$tagPos) {\n            throw new Exception('Can not clone row, template variable not found or variable contains markup.');\n        }\n\n        $rowStart = $this->findRowStart($tagPos);\n        $rowEnd = $this->findRowEnd($tagPos);\n        $xmlRow = $this->getSlice($rowStart, $rowEnd);\n\n        // Check if there's a cell spanning multiple rows.\n        if (preg_match('#<w:vMerge w:val=\"restart\"/>#', $xmlRow)) {\n            // $extraRowStart = $rowEnd;\n            $extraRowEnd = $rowEnd;\n            while (true) {\n                $extraRowStart = $this->findRowStart($extraRowEnd + 1);\n                $extraRowEnd = $this->findRowEnd($extraRowEnd + 1);\n\n                // If extraRowEnd is lower then 7, there was no next row found.\n                if ($extraRowEnd < 7) {\n                    break;\n                }","sourceCodeStart":750,"sourceCodeEnd":786,"githubUrl":"https://github.com/PHPOffice/PHPWord/blob/aef95c04151b5633cc505f672ddd6a71da900ee1/src/PhpWord/TemplateProcessor.php#L750-L786","documentation":"TemplateProcessor::cloneRow searches the main document part for the completed macro '${search}'; if strpos returns false (or 0-falsy) it throws 'Can not clone row, template variable not found or variable contains markup.' — meaning the variable text is absent, split across XML runs (markup inside it), or the search did not match.","triggerScenarios":"cloneRow('variable', n) where '${variable}' is not in the template, or Word split the placeholder into multiple <w:t> runs due to spell-check/formatting so the contiguous string does not exist in the raw XML; also triggers when the placeholder is at position 0 handled incorrectly or in headers/footers (cloneRow only searches the main part).","commonSituations":"Placeholders typed into Word where autocorrect/spellcheck breaks them into separate XML runs; variable placed in a table in a header instead of the body; typo in variable name; missing ${...} delimiters in the search argument.","solutions":["Retype the placeholder in Word as plain text (paste into Notepad first, then retype in the cell) to keep it in a single XML run","Call $processor->cloneRow('variable', $n) with the bare variable name — ensureMacroCompleted adds ${}","Verify the placeholder exists in the main body (not header/footer) by checking the template XML","Ensure the template variable is in a table row (cloneRow is for table rows only)","Use setValue before inspecting, or inspect the saved XML to confirm the exact placeholder text"],"exampleFix":"// before\n$processor->cloneRow('${rowId}', 3); // wrong: no ${} needed, may not match\n// after\n$processor->cloneRow('rowId', 3);\n$processor->setValue('rowId#1', 'first');","handlingStrategy":"try-catch","validationCode":"$snippet = file_get_contents('template.docx'); // or inspect raw main part\n// verify the placeholder survives as a contiguous string in the XML:\n$hasMacro = strpos($mainPartXml, '${rowId}') !== false;\nif (!$hasMacro) {\n    throw new RuntimeException('Placeholder ${rowId} split across XML runs or missing');\n}","typeGuard":null,"tryCatchPattern":"try {\n    $template->cloneRow('rowId', 3);\n} catch (\\PhpOffice\\PhpWord\\Exception\\Exception $e) {\n    if (str_contains($e->getMessage(), 'Can not clone row')) {\n        // retype placeholder in Word as plain text and re-check\n    }\n}","preventionTips":["Pass the bare variable name to cloneRow (no ${}); it adds the macro itself","Type placeholders as plain text; avoid editing mid-placeholder in Word","Keep table-row placeholders in the document body, not headers/footers","Diff the raw document.xml to confirm the placeholder is one contiguous string"],"tags":["template","docx","placeholder"],"backgroundTag":"resource-not-found","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"}