{"record":{"id":"a045c815e3f09152","repo":"octobercms/october","slug":"invalid-documentmetadata-a045c8","errorCode":null,"errorMessage":"Invalid documentMetadata","messagePattern":"Invalid documentMetadata","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"modules/tailor/classes/editorextension/HasExtensionCrud.php","lineNumber":287,"sourceCode":"\n        $result = [\n            'mtime' => $template->mtime,\n            'path' => $fileName,\n            'type' => $documentType,\n            'typeName' => $typeNames[$documentType]\n        ];\n\n        return $result;\n    }\n\n    /**\n     * getRequestMetadata\n     */\n    private function getRequestMetadata()\n    {\n        $metadata = Request::input('documentMetadata');\n        if (!is_array($metadata)) {\n            throw new SystemException('Invalid documentMetadata');\n        }\n\n        return $metadata;\n    }\n\n    /**\n     * getRequestExtraData\n     */\n    private function getRequestExtraData()\n    {\n        $extraData = Request::input('extraData');\n        if (!is_array($extraData)) {\n            return [];\n        }\n\n        return $extraData;\n    }\n","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/tailor/classes/editorextension/HasExtensionCrud.php#L269-L305","documentation":"getRequestMetadata() reads `documentMetadata` from the current request and requires an array. Editor extension commands (e.g. save) depend on it — mtime, path, type — to detect concurrent-edit conflicts. Missing, string, or null input throws SystemException('Invalid documentMetadata').","triggerScenarios":"Invoking an editor extension AJAX command that calls getRequestMetadata() without supplying documentMetadata, or sending it serialized as a JSON string rather than an array of form values.","commonSituations":"Custom editor integrations that don't round-trip the metadata returned by onOpenDocument; automated tests hitting handlers directly; payload shape drift after CMS upgrades.","solutions":["Include documentMetadata as an array mirroring what onOpenDocument returned (path, type, mtime at minimum).","In custom clients, echo back the exact metadata object the editor provided on open.","After upgrades, clear cached editor assets so the shipped client payload is used."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"$metadata = \\Request::input('documentMetadata');\nif (!is_array($metadata) || !isset($metadata['path'], $metadata['type'])) {\n    throw new InvalidArgumentException('documentMetadata array with path and type is required.');\n}","typeGuard":"function isValidDocumentMetadata($metadata): bool\n{\n    return is_array($metadata) && isset($metadata['path'], $metadata['type']);\n}","tryCatchPattern":"try {\n    $metadata = $this->getRequestMetadata();\n} catch (\\SystemException $e) {\n    // request malformed — respond 422 and have the client re-open the document to obtain metadata\n}","preventionTips":["Round-trip the metadata object returned by onOpenDocument in every subsequent save request.","Contract-test custom editor integrations for the presence of documentMetadata."],"tags":["tailor","editor-extension","ajax","request-payload"],"backgroundTag":"missing-request-payload","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}