{"record":{"id":"4ffe041f72740d97","repo":"hashicorp/nomad","slug":"failed-to-parse-follow-field-to-boolean-v","errorCode":null,"errorMessage":"failed to parse follow field to boolean: %v","messagePattern":"failed to parse follow field to boolean: (.+?)","errorType":"http","errorClass":null,"httpStatus":400,"severity":"error","filePath":"command/agent/fs_endpoint.go","lineNumber":225,"sourceCode":"//     applied. Defaults to \"start\".\nfunc (s *HTTPServer) Stream(resp http.ResponseWriter, req *http.Request) (any, error) {\n\tvar allocID, path string\n\tvar err error\n\n\tq := req.URL.Query()\n\n\tif allocID = strings.TrimPrefix(req.URL.Path, \"/v1/client/fs/stream/\"); allocID == \"\" {\n\t\treturn nil, allocIDNotPresentErr\n\t}\n\n\tif path = q.Get(\"path\"); path == \"\" {\n\t\treturn nil, fileNameNotPresentErr\n\t}\n\n\tfollow := true\n\tif followStr := q.Get(\"follow\"); followStr != \"\" {\n\t\tif follow, err = strconv.ParseBool(followStr); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to parse follow field to boolean: %v\", err)\n\t\t}\n\t}\n\n\tvar offset int64\n\toffsetString := q.Get(\"offset\")\n\tif offsetString != \"\" {\n\t\tif offset, err = strconv.ParseInt(offsetString, 10, 64); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error parsing offset: %v\", err)\n\t\t}\n\t}\n\n\torigin := q.Get(\"origin\")\n\tswitch origin {\n\tcase \"start\", \"end\":\n\tcase \"\":\n\t\torigin = \"start\"\n\tdefault:\n\t\treturn nil, invalidOrigin","sourceCodeStart":207,"sourceCodeEnd":243,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/fs_endpoint.go#L207-L243","documentation":"Returned by the file/log streaming endpoint's Stream handler (command/agent/fs_endpoint.go:225) when the `follow` query parameter is present but fails strconv.ParseBool. follow defaults to true, so the error only occurs when a caller explicitly supplies a value outside Go's accepted boolean literals.","triggerScenarios":"Calling GET /v1/client/fs/stream or /v1/client/fs/logs with follow=<v> where v is not one of 1,t,T,TRUE,true,True,0,f,F,FALSE,false,False — e.g. follow=yes, follow=on, or follow=true with a trailing space.","commonSituations":"Using shell-style yes/no/on/off conventions; templating injecting whitespace or quotes; languages rendering booleans differently than Go; typos like follow=truee.","solutions":["Send follow=true or follow=false — only Go bool literals are accepted.","Omit the parameter to accept the default (true).","Normalize client-side with strconv.FormatBool(myBool) before URL-encoding.","Trim whitespace and strip stray quotes from templated values before sending."],"exampleFix":"// before\ncurl -N \"http://localhost:4646/v1/client/fs/logs?alloc_id=abc&follow=yes\"\n// after\ncurl -N \"http://localhost:4646/v1/client/fs/logs?alloc_id=abc&follow=true\"","handlingStrategy":"validation","validationCode":"if f := q.Get(\"follow\"); f != \"\" {\n    if _, err := strconv.ParseBool(f); err != nil {\n        return fmt.Errorf(\"follow must be a Go bool literal, got %q\", f)\n    }\n}","typeGuard":"func validFollow(s string) bool {\n    if s == \"\" { return true }\n    _, err := strconv.ParseBool(s)\n    return err == nil\n}","tryCatchPattern":"if err != nil {\n    if strings.Contains(err.Error(), \"failed to parse follow field\") {\n        // retry with the default follow=true\n        q.Set(\"follow\", \"true\")\n    }\n}","preventionTips":["Use strconv.FormatBool or a typed SDK option, not raw strings.","Never send yes/no/on/off — ParseBool accepts only Go bool literals.","Trim and de-quote templated input before URL-encoding.","Omit the parameter to accept the endpoint default."],"tags":["http-api","query-params","parsing","boolean","nomad"],"backgroundTag":"invalid-query-parameter","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}