{"record":{"id":"3c83a0cc8c6cdfab","repo":"dompdf/dompdf","slug":"parent-table-not-found-for-table-row-group","errorCode":null,"errorMessage":"Parent table not found for table row group","messagePattern":"Parent table not found for table row group","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/FrameReflower/TableRowGroup.php","lineNumber":66,"sourceCode":"        foreach ($frame->get_children() as $child) {\n            $child->set_containing_block($cb[\"x\"], $cb[\"y\"], $cb[\"w\"], $cb[\"h\"]);\n            $child->reflow();\n\n            // Check if a split has occurred\n            $page->check_page_break($child);\n\n            if ($page->is_full()) {\n                break;\n            }\n        }\n\n        if ($page->is_full() && $dompdf_generated && $frame->get_parent() === null) {\n            return;\n        }\n\n        $table = TableFrameDecorator::find_parent_table($frame);\n        if ($table === null) {\n            throw new Exception(\"Parent table not found for table row group\");\n        }\n        $cellmap = $table->get_cellmap();\n\n        // Stop reflow if a page break has occurred before the frame, in which\n        // case it is not part of its parent table's cell map yet\n        if ($page->is_full() && !$cellmap->frame_exists_in_cellmap($frame)) {\n            return;\n        }\n\n        $style->set_used(\"width\", $cellmap->get_frame_width($frame));\n        $style->set_used(\"height\", $cellmap->get_frame_height($frame));\n\n        $frame->set_position($cellmap->get_frame_position($frame));\n    }\n}\n","sourceCodeStart":48,"sourceCodeEnd":82,"githubUrl":"https://github.com/dompdf/dompdf/blob/b14267808b811db092f53830f81f4706f4917c79/src/FrameReflower/TableRowGroup.php#L48-L82","documentation":"Thrown at the tail of TableRowGroup::reflow(): a tbody-like group reads its final size and position from the ancestor table's cellmap, found via TableFrameDecorator::find_parent_table(). When no table ancestor exists, the group frame is orphaned and the exception aborts render(). Same family as the row/cell 'Parent table not found' errors, one level up the table structure.","triggerScenarios":"A display:table-row-group frame (a <tbody>, or element styled that way) is reflowed without any table ancestor — stray <tbody> in markup, or a group frame detached from its table during page-break/split handling. Note the preceding code already returns early for dompdf-generated groups on full pages, so this throw is for genuinely table-less groups.","commonSituations":"Templates or sanitizers that strip <table> but leave <tbody>; HTML built by string concatenation where the opening <table> tag is lost; page-break-inside:avoid on large tbody groups triggering split edge cases in older dompdf builds.","solutions":["Fix the source HTML so every <tbody> is inside <table>","Run user content through an HTML5 normalizer (tidy, masterminds/html5) before load_html()","Avoid page-break-inside:avoid on very large tbody groups that must split across pages","Update dompdf to benefit from row-group split fixes"],"exampleFix":"// before\n$html = '<tbody><tr><td>a</td></tr></tbody>';\n\n// after\n$html = '<table><tbody><tr><td>a</td></tr></tbody></table>';","handlingStrategy":"validation","validationCode":"function rowGroupsHaveTables(string $html): bool {\n    $doc = new DOMDocument();\n    $doc->loadHTML($html, LIBXML_NOWARNING | LIBXML_NOERROR);\n    foreach ($doc->getElementsByTagName('tbody') as $tb) {\n        for ($n = $tb->parentNode; $n !== null; $n = $n->parentNode) {\n            if (strtolower($n->nodeName) === 'table') continue 2;\n        }\n        return false;\n    }\n    return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n    $dompdf->render();\n} catch (\\Exception $e) {\n    if (str_contains($e->getMessage(), 'Parent table not found for table row group')) {\n        throw new DocumentValidationException('Malformed table: row group outside table.', 0, $e);\n    }\n    throw $e;\n}","preventionTips":["Ensure sanitizers never strip <table> while keeping <tbody>","Avoid page-break-inside:avoid on tbodys that must split across pages","Keep dompdf updated for row-group splitting fixes"],"tags":["dompdf","tables","table-row-group","malformed-html","reflow"],"backgroundTag":"malformed-html-structure","analyzedSha":"b14267808b811db092f53830f81f4706f4917c79","analyzedAt":"2026-08-21T03:01:11.111Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}