{"record":{"id":"8e314523ef868900","repo":"caddyserver/caddy","slug":"malformed-object-path","errorCode":null,"errorMessage":"malformed object path","messagePattern":"malformed object path","errorType":"http","errorClass":"APIError","httpStatus":400,"severity":"error","filePath":"admin.go","lineNumber":1104,"sourceCode":"\t}\n\n\treturn nil\n}\n\nfunc handleConfigID(w http.ResponseWriter, r *http.Request) error {\n\tidPath := r.URL.Path\n\n\tparts := strings.Split(idPath, \"/\")\n\tif len(parts) < 3 || parts[2] == \"\" {\n\t\treturn APIError{\n\t\t\tHTTPStatus: http.StatusBadRequest,\n\t\t\tErr:        fmt.Errorf(\"request path is missing object ID\"),\n\t\t}\n\t}\n\tif parts[0] != \"\" || parts[1] != \"id\" {\n\t\treturn APIError{\n\t\t\tHTTPStatus: http.StatusBadRequest,\n\t\t\tErr:        fmt.Errorf(\"malformed object path\"),\n\t\t}\n\t}\n\tid := parts[2]\n\n\t// map the ID to the expanded path\n\trawCfgMu.RLock()\n\texpanded, ok := rawCfgIndex[id]\n\trawCfgMu.RUnlock()\n\tif !ok {\n\t\treturn APIError{\n\t\t\tHTTPStatus: http.StatusNotFound,\n\t\t\tErr:        fmt.Errorf(\"unknown object ID '%s'\", id),\n\t\t}\n\t}\n\n\t// piece the full URL path back together\n\tparts = append([]string{expanded}, parts[3:]...)\n\tr.URL.Path = path.Join(parts...)","sourceCodeStart":1086,"sourceCodeEnd":1122,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/admin.go#L1086-L1122","documentation":"Thrown by handleConfigID in Caddy's admin API when the request path's second segment is not the literal 'id'. After splitting on '/', the code requires parts[0]==\"\" and parts[1]==\"id\"; anything else (e.g. '/ids/foo' or '/ID/foo') yields HTTP 400 'malformed object path'.","triggerScenarios":"Requests like GET /ids/my-route (typo in the 'id' prefix), /ID/foo (wrong case), or a path where the first segment is not empty. Any /id-style URL that does not start exactly with /id/.","commonSituations":"Typos in the endpoint prefix; clients that prepend an extra path component or base path so the split alignment shifts; assuming case-insensitive endpoints.","solutions":["Use the exact prefix /id/ directly after the admin address, e.g. http://localhost:2019/id/<ID>","Check for a doubled path segment or base-URL joining bug in your HTTP client that shifts the path parts","Remember the prefix is case-sensitive lowercase 'id'"],"exampleFix":"# before\ncurl http://localhost:2019/ids/my-route\n# after\ncurl http://localhost:2019/id/my-route","handlingStrategy":"validation","validationCode":"import re\ndef valid_id_url(url: str) -> bool:\n    return re.fullmatch(r\"https?://[^/]+/id/[^/]+\", url) is not None","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Centralize admin URL construction in one helper that always emits /id/<ID>","The prefix is lowercase 'id' and case-sensitive"],"tags":["caddy","admin-api","http","routing","bad-request"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}