{"record":{"id":"1926bb76af45207d","repo":"octobercms/october","slug":"cms-lang-partial-invalid-name","errorCode":null,"errorMessage":"cms::lang.partial.invalid_name","messagePattern":"cms::lang\\.partial\\.invalid_name","errorType":"exception","errorClass":"CmsException","httpStatus":null,"severity":"error","filePath":"modules/cms/classes/controller/HasAjaxRequests.php","lineNumber":101,"sourceCode":"        // Execute AJAX event\n        if ($ajaxResponse = $this->execAjaxHandlers()) {\n            return $ajaxResponse;\n        }\n    }\n\n    /**\n     * getAjaxHandlerPartialList\n     */\n    protected function getAjaxHandlerPartialList(): array\n    {\n        $request = $this->getAjaxRequest();\n\n        if ($request->hasAjaxHandler()) {\n            $partials = $request->partialList;\n\n            foreach ($partials as $partial) {\n                if (!Partial::validateRequestName($partial)) {\n                    throw new CmsException(Lang::get('cms::lang.partial.invalid_name', ['name'=>e($partial)]));\n                }\n            }\n\n            return $partials;\n        }\n\n        return [];\n    }\n\n    /**\n     * execAjaxHandlers executes the page, layout, component and plugin AJAX handlers.\n     * @return mixed Returns the AJAX Response object or null.\n     */\n    protected function execAjaxHandlers()\n    {\n        $handler = $this->getAjaxHandler();\n        if (!$handler) {\n            return null;","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/cms/classes/controller/HasAjaxRequests.php#L83-L119","documentation":"During an AJAX request, every partial name in the update/partial list is validated by Partial::validateRequestName() before rendering. Valid names are letters, digits, '_', '-', '.', '/' with an optional '@' or 'componentAlias::' prefix; names containing '..', './', '//', spaces or other characters are rejected with this CmsException before the handler response is assembled.","triggerScenarios":"An AJAX request whose partial update list (data-request-update / the winter.ajax.js partialList) contains a selector like 'my partial', '../theme/partials/x', 'foo//bar', 'foo/bar/', a backslash path, or a misspelled 'Alias::partial' reference.","commonSituations":"Hand-built AJAX payloads instead of the framework JS; markup copied between projects keeping invalid selectors; partial paths typed with Windows separators or stray whitespace; security probes sending traversal strings.","solutions":["Use a plain relative path under the theme's partials/ directory, e.g. 'cards/card'","Prefix component partials correctly: '@alias/partial' or 'alias::partialname'","Strip any '../', '//' or whitespace from the selector","When issuing requests manually, reuse the data-request/data-request-update API so partial names come from valid template paths"],"exampleFix":"<!-- before -->\n<div data-request=\"onSave\" data-request-update=\"../partials/card '#card'\"></div>\n\n<!-- after -->\n<div data-request=\"onSave\" data-request-update=\"cards/card '#card'\"></div>","handlingStrategy":"validation","validationCode":"use \\Cms\\Classes\\Partial;\nforeach ($requestPartialList as $name) {\n    if (!Partial::validateRequestName($name)) {\n        throw new InvalidArgumentException('Invalid partial name: '.$name);\n    }\n}","typeGuard":"function isValidPartialName(name) {\n  return /^(?:\\w+::|@)?[a-z0-9_.\\/-]+$/i.test(name) && !name.includes('..') && !name.includes('./') && !name.includes('//');\n}","tryCatchPattern":"try { $.request(handler, { update: partials }); } catch (e) { /* inspect partial names in the update map, correct and re-issue */ }","preventionTips":["Generate partial selectors from actual template paths, never concatenate raw user input","Use the framework data-request-update API instead of hand-built partial lists","Add a client-side sanity regex before sending requests when partial names are dynamic"],"tags":["ajax","partials","cms","validation","user-input"],"backgroundTag":"request-validation-failed","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}