{"record":{"id":"f461580303aef666","repo":"octobercms/october","slug":"unknown-document-type-s-f46158","errorCode":null,"errorMessage":"Unknown document type: %s","messagePattern":"Unknown document type: (.+?)","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"modules/tailor/classes/EditorExtension.php","lineNumber":148,"sourceCode":"\n    /**\n     * getNewDocumentsData\n     */\n    public function getNewDocumentsData()\n    {\n        return [\n            EditorExtension::DOCUMENT_TYPE_BLUEPRINT => $this->getTailorBlueprintNewDocumentData(),\n            EditorExtension::DOCUMENT_TYPE_THEME_BLUEPRINT => $this->getTailorThemeBlueprintNewDocumentData()\n        ];\n    }\n\n    /**\n     * hasAccessToDocType\n     */\n    public static function hasAccessToDocType($user, $documentType)\n    {\n        if (!array_key_exists($documentType, EditorExtension::DOCUMENT_TYPE_PERMISSIONS)) {\n            throw new SystemException(sprintf('Unknown document type: %s', $documentType));\n        }\n\n        return $user->hasAnyAccess(EditorExtension::DOCUMENT_TYPE_PERMISSIONS[$documentType]);\n    }\n\n    /**\n     * getCustomData returns custom state data required for the extension client-side controller\n     */\n    public function getCustomData(): array\n    {\n        return [\n            'blueprintTemplates' => [\n                'entry' => $this->getBlueprintTemplate('entry'),\n                'single' => $this->getBlueprintTemplate('single'),\n                'stream' => $this->getBlueprintTemplate('stream'),\n                'structure' => $this->getBlueprintTemplate('structure'),\n                'mixin' => $this->getBlueprintTemplate('mixin'),\n                'global' => $this->getBlueprintTemplate('global'),","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/tailor/classes/EditorExtension.php#L130-L166","documentation":"EditorExtension::hasAccessToDocType() maps a document type to required backend permissions via the DOCUMENT_TYPE_PERMISSIONS map, which only registers 'tailor-blueprint' and 'tailor-theme-blueprint'. Any other string (or null) is rejected with sprintf('Unknown document type: %s') before permission checks even run.","triggerScenarios":"Calling EditorExtension::hasAccessToDocType($user, $type) with a hand-built string like 'blueprint' or 'tailor_blueprint' instead of the EditorExtension::DOCUMENT_TYPE_* constants; the editor extension client sending an unexpected `type` value in documentData.","commonSituations":"Custom code integrating with the editor extension API; typo'd type literals; payloads from older versions after a CMS upgrade; tests calling the method with arbitrary strings.","solutions":["Pass EditorExtension::DOCUMENT_TYPE_BLUEPRINT ('tailor-blueprint') or EditorExtension::DOCUMENT_TYPE_THEME_BLUEPRINT ('tailor-theme-blueprint') — use the constants, not literals.","When handling client input, validate the type against array_keys(EditorExtension::DOCUMENT_TYPE_PERMISSIONS) before calling hasAccessToDocType()."],"exampleFix":"// before\nEditorExtension::hasAccessToDocType($user, 'blueprint');\n\n// after\nEditorExtension::hasAccessToDocType($user, EditorExtension::DOCUMENT_TYPE_BLUEPRINT);","handlingStrategy":"type-guard","validationCode":"$known = array_keys(\\Tailor\\Classes\\EditorExtension::DOCUMENT_TYPE_PERMISSIONS);\nif (!in_array($documentType, $known, true)) {\n    throw new InvalidArgumentException('Unknown document type: ' . $documentType);\n}","typeGuard":"function isKnownTailorDocumentType($type): bool\n{\n    return is_string($type) && array_key_exists(\n        $type,\n        \\Tailor\\Classes\\EditorExtension::DOCUMENT_TYPE_PERMISSIONS\n    );\n}","tryCatchPattern":"try {\n    EditorExtension::hasAccessToDocType($user, $documentType);\n} catch (\\SystemException $e) {\n    // reject/log the malformed document type before it reaches permission logic\n}","preventionTips":["Always use the EditorExtension::DOCUMENT_TYPE_* constants instead of string literals.","Validate document types at the request boundary when accepting editor extension payloads from clients."],"tags":["tailor","editor-extension","document-type","api-misuse"],"backgroundTag":"invalid-enum-value","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}