{"record":{"id":"45270feedc403e2d","repo":"caddyserver/caddy","slug":"invalid-traversal-path-at-s","errorCode":null,"errorMessage":"invalid traversal path at: %s","messagePattern":"invalid traversal path at: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"admin.go","lineNumber":1331,"sourceCode":"\t\t\t\t\tv[part] = make(map[string]any)\n\t\t\t\t}\n\t\t\t\tptr = v[part]\n\t\t\t}\n\n\t\tcase []any:\n\t\t\tpartInt, err := parseCanonicalArrayIndex(part)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"[/%s] invalid array index '%s': %v\",\n\t\t\t\t\tstrings.Join(parts[:i+1], \"/\"), part, err)\n\t\t\t}\n\t\t\tif partInt < 0 || partInt >= len(v) {\n\t\t\t\treturn fmt.Errorf(\"[/%s] array index out of bounds: %s\",\n\t\t\t\t\tstrings.Join(parts[:i+1], \"/\"), part)\n\t\t\t}\n\t\t\tptr = v[partInt]\n\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"invalid traversal path at: %s\", strings.Join(parts[:i+1], \"/\"))\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// RemoveMetaFields removes meta fields like \"@id\" from a JSON message\n// by using a simple regular expression. (An alternate way to do this\n// would be to delete them from the raw, map[string]any\n// representation as they are indexed, then iterate the index we made\n// and add them back after encoding as JSON, but this is simpler.)\nfunc RemoveMetaFields(rawJSON []byte) []byte {\n\treturn idRegexp.ReplaceAllFunc(rawJSON, func(in []byte) []byte {\n\t\t// matches with a comma on both sides (when \"@id\" property is\n\t\t// not the first or last in the object) need to keep exactly\n\t\t// one comma for correct JSON syntax\n\t\tcomma := []byte{','}\n\t\tif bytes.HasPrefix(in, comma) && bytes.HasSuffix(in, comma) {","sourceCodeStart":1313,"sourceCodeEnd":1349,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/admin.go#L1313-L1349","documentation":"Thrown when a traversal step lands on a config node that is neither a map nor an array — typically a scalar (string, number, bool) — yet the path continues with more segments. The message names the prefix up to and including the offending segment, e.g. 'invalid traversal path at: apps/http/servers/myserver/listen' when something like /0 is appended after listen.","triggerScenarios":"GET /config/apps/http/servers/myserver/listen/0 where listen is a JSON array of strings but the scalar case occurs for e.g. .../automatic_https/disable/next, or any path that keeps descending after reaching a string/number/bool leaf such as .../listen/0/extra.","commonSituations":"Misjudging the config schema depth: treating a leaf scalar as a traversable container; appending extra segments after a full address like admin/timeout/... ; paths built by naive splitting of a desired dotted path.","solutions":["GET the exact prefix from the error message to see the node's actual type","End the path at the scalar, e.g. .../listen/0 instead of .../listen/0/x","Cross-check against the JSON config schema docs for leaf node types"],"exampleFix":"# before: '0' is a string leaf, cannot descend further\ncurl http://localhost:2019/config/apps/http/servers/myserver/listen/0/x\n# after\ncurl http://localhost:2019/config/apps/http/servers/myserver/listen/0","handlingStrategy":"type-guard","validationCode":"prefix=\"apps/http/servers/myserver/listen\"\ntype=$(curl -s \"http://localhost:2019/config/$prefix\" | jq -r 'type')\n[ \"$type\" = \"object\" -o \"$type\" = \"array\" ] && echo \"traversable\" || echo \"leaf — stop here\"","typeGuard":"func traversable(v any) bool {\n    switch v.(type) {\n    case map[string]any, []any:\n        return true\n    }\n    return false\n}","tryCatchPattern":"Parse 'invalid traversal path at: <prefix>', GET that prefix to see its JSON type, and truncate or correct the path so it stops at or correctly indexes that node.","preventionTips":["Know your schema: leaves like listen/0 are strings and cannot be descended into","When in doubt, GET each level incrementally while constructing the path"],"tags":["caddy","admin-api","config","path","bad-request"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}