{"record":{"id":"2ab7c1c186d64080","repo":"caddyserver/caddy","slug":"only-max-2-sort-options-are-allowed-but-got-d","errorCode":null,"errorMessage":"only max 2 sort options are allowed, but got %d","messagePattern":"only max 2 sort options are allowed, but got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/caddyhttp/fileserver/staticfiles.go","lineNumber":261,"sourceCode":"\t\t\tfsrv.precompressors = make(map[string]encode.Precompressed)\n\t\t}\n\t\tfsrv.precompressors[ae] = p\n\t}\n\n\tif fsrv.Browse != nil {\n\t\t// check sort options\n\t\tfor idx, sortOption := range fsrv.Browse.SortOptions {\n\t\t\tswitch idx {\n\t\t\tcase 0:\n\t\t\t\tif sortOption != sortByName && sortOption != sortByNameDirFirst && sortOption != sortBySize && sortOption != sortByTime {\n\t\t\t\t\treturn fmt.Errorf(\"the first option must be one of the following: %s, %s, %s, %s, but got %s\", sortByName, sortByNameDirFirst, sortBySize, sortByTime, sortOption)\n\t\t\t\t}\n\t\t\tcase 1:\n\t\t\t\tif sortOption != sortOrderAsc && sortOption != sortOrderDesc {\n\t\t\t\t\treturn fmt.Errorf(\"the second option must be one of the following: %s, %s, but got %s\", sortOrderAsc, sortOrderDesc, sortOption)\n\t\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn fmt.Errorf(\"only max 2 sort options are allowed, but got %d\", idx+1)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {\n\trepl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)\n\n\tif runtime.GOOS == \"windows\" {\n\t\t// reject paths with Alternate Data Streams (ADS)\n\t\tif strings.Contains(r.URL.Path, \":\") {\n\t\t\treturn caddyhttp.Error(http.StatusBadRequest, fmt.Errorf(\"illegal ADS path\"))\n\t\t}\n\t\t// reject paths with \"8.3\" short names\n\t\ttrimmedPath := strings.TrimRight(r.URL.Path, \". \") // Windows ignores trailing dots and spaces, sigh\n\t\tif len(path.Base(trimmedPath)) <= 12 && strings.Contains(trimmedPath, \"~\") {","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/modules/caddyhttp/fileserver/staticfiles.go#L243-L279","documentation":"Returned in FileServer.Provision when browse sort_options contains more than two entries. The schema is exactly [sort_key] and optionally [direction]; the loop's default case rejects any third element (idx == 2, reported as idx+1 == 3 options).","triggerScenarios":"sort_options lists three or more tokens, e.g. `sort_options name asc size`, or a JSON array with 3+ strings under browse.sort_options.","commonSituations":"Trying to express multi-level sorting; pasting option lists from documentation of other index modules; iterating on config and leaving stale tokens.","solutions":["Trim sort_options to at most two tokens: one sort key, optionally one direction.","Delete the extra tokens from the Caddyfile or JSON array.","Validate config before reload: `caddy validate --config <file>`."],"exampleFix":"# before\nsort_options name asc size\n# after\nsort_options name asc","handlingStrategy":"validation","validationCode":"# Pre-deploy check: at most 2 tokens after sort_options\nn=$(awk '/sort_options/{print NF-1}' Caddyfile)\n[ \"$n\" -le 2 ] || { echo \"too many sort_options ($n); max 2\"; exit 1; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["sort_options has a hard cap of two entries.","Avoid pasting long option lists from other index modules.","Validate config in CI to catch overlong lists before deploy."],"tags":["caddy","fileserver","browse","sort-options","config-validation"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}