{"record":{"id":"20b6663d7fe2ddaf","repo":"getgrav/grav","slug":"400","errorCode":"400","errorMessage":"Page content resolves to disallowed markup (%s) after Twig processing. Remove the render-time-assembled tag or attribute.","messagePattern":"Page content resolves to disallowed markup \\((.+?)\\) after Twig processing\\. Remove the render-time-assembled tag or attribute\\.","errorType":"validation","errorClass":"RuntimeException","httpStatus":400,"severity":"error","filePath":"system/src/Grav/Common/Flex/Types/Pages/PageObject.php","lineNumber":196,"sourceCode":"\n    /**\n     * @param array $variables\n     * @return array\n     */\n    protected function onBeforeSave(array $variables)\n    {\n        $reorder = $variables[0] ?? true;\n\n        // Render-time XSS backstop, enforced at save. Editor-authored Twig in\n        // page content can assemble markup the raw-source validator can't see\n        // (`{{ \"on\" ~ \"error\" }}`, `<s{{ \"cript\" }}>`); render the sandboxed\n        // content-Twig in isolation and reject the save if it resolves to flagged\n        // markup. Only editor content is in scope here — no shortcodes/plugins\n        // have run — so trusted plugin/theme output can never trip it. Superadmins\n        // are exempt (mirrors the raw-source checkSafety). (GHSA-2c4f-86xc-cr74)\n        $found = Security::detectXssInEditorContent($this->getRawContent(), $this);\n        if ($found !== null) {\n            throw new RuntimeException(\n                sprintf('Page content resolves to disallowed markup (%s) after Twig processing. Remove the render-time-assembled tag or attribute.', $found),\n                400\n            );\n        }\n\n        $meta = $this->getMetaData();\n        if (($meta['copy'] ?? false) === true) {\n            $this->folder = $this->getKey();\n        }\n\n        // Figure out storage path to the new route.\n        $parentKey = $this->getProperty('parent_key');\n        if ($parentKey !== '') {\n            $parentRoute = $this->getProperty('route');\n\n            // Root page cannot be moved.\n            if ($this->root()) {\n                throw new RuntimeException(sprintf('Root page cannot be moved to %s', $parentRoute));","sourceCodeStart":178,"sourceCodeEnd":214,"githubUrl":"https://github.com/getgrav/grav/blob/6040efed04efa69b8209448ed81308e7c24147c2/system/src/Grav/Common/Flex/Types/Pages/PageObject.php#L178-L214","documentation":"Error \"Page content resolves to disallowed markup (%s) after Twig processing. Remove the render-time-assembled tag or attribute.\" thrown in getgrav/grav.","triggerScenarios":"Thrown at system/src/Grav/Common/Flex/Types/Pages/PageObject.php:196 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":[],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6040efed04efa69b8209448ed81308e7c24147c2","analyzedAt":"2026-08-17T05:07:31.593Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}