octobercms/october · error · SystemException

Document type name is not defined: %s

Error message

Document type name is not defined: %s

What it means

When building metadata for a loaded template, loadTemplateMetadata() looks up a human-readable type name in a fixed map of the six document types; a type missing from that map throws 'Document type name is not defined: %s'. In stock flows resolveTypeClassName() filters unknown types earlier, so this is reached mainly with custom or dynamically-injected document types.

Source

Thrown at modules/cms/classes/editorextension/HasExtensionCrud.php:311

     * loadTemplateMetadata
     */
    private function loadTemplateMetadata($template, $documentData)
    {
        $theme = $this->getTheme();
        $themeDirName = $theme->getDirName();

        $typeNames = [
            EditorExtension::DOCUMENT_TYPE_PAGE => Lang::get('cms::lang.editor.page'),
            EditorExtension::DOCUMENT_TYPE_LAYOUT => Lang::get('cms::lang.editor.layout'),
            EditorExtension::DOCUMENT_TYPE_PARTIAL => Lang::get('cms::lang.editor.partial'),
            EditorExtension::DOCUMENT_TYPE_CONTENT => Lang::get('cms::lang.editor.content'),
            EditorExtension::DOCUMENT_TYPE_ASSET => Lang::get('cms::lang.editor.asset'),
            EditorExtension::DOCUMENT_TYPE_LANG => Lang::get('cms::lang.editor.lang')
        ];

        $documentType = $documentData['type'];
        if (!array_key_exists($documentType, $typeNames)) {
            throw new SystemException(sprintf('Document type name is not defined: %s', $documentData['type']));
        }

        $typeDirName = $this->getDocumentTypeDirName($template);
        $fileName = ltrim($template->fileName, '/');

        $result = [
            'mtime' => $template->mtime,
            'path' => $fileName,
            'theme' => $themeDirName,
            'canUpdateTemplateFile' => $this->canUpdateTemplateFile($template),
            'canResetFromTemplateFile' => $this->canResetFromTemplateFile($template),
            'fullPath' => $typeDirName.'/'.$fileName,
            'type' => $documentType,
            'typeName' => $typeNames[$documentType]
        ];

        return $result;
    }

View on GitHub (pinned to b608633a7e)

Solutions

  1. Restrict requests to the six built-in document types
  2. If you need custom types, hook the editor extension consistently so load, metadata and save all understand them
  3. Upgrade Winter so all type maps come from the same version
Defensive patterns

Strategy: validation

Validate before calling

$knownTypes = ['page', 'partial', 'layout', 'content', 'asset', 'lang'];
if (!in_array($documentData['type'] ?? null, $knownTypes, true)) {
    // do not build metadata for custom types; map them yourself before calling
}

Type guard

function hasKnownTypeName(documentData) {
  return ['page', 'partial', 'layout', 'content', 'asset', 'lang'].includes(documentData?.type);
}

Prevention

When it happens

Trigger: documentData['type'] resolves during loading (e.g. via a hooked event or third-party extension injecting custom types) but is not one of page|partial|layout|content|asset|lang when metadata is generated.

Common situations: Plugins adding custom editor document types without extending every type map; inconsistent payloads between editor commands; version drift where type maps across traits come from different module versions.

Related errors


AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21). Data as JSON: /api/errors/c151261d1f65abb9. Report an issue: GitHub.