{"record":{"id":"adaf5e05336e6dc7","repo":"plandex-ai/plandex","slug":"error-decoding-auth-token-v","errorCode":null,"errorMessage":"error decoding auth token: %v","messagePattern":"error decoding auth token: (.+?)","errorType":"validation","errorClass":null,"httpStatus":401,"severity":"error","filePath":"app/server/handlers/auth_helpers.go","lineNumber":66,"sourceCode":"\t\tlog.Println(\"got auth header from cookie\")\n\t}\n\n\tif authHeader == \"\" {\n\t\treturn nil, nil\n\t}\n\n\tif !strings.HasPrefix(authHeader, \"Bearer \") {\n\t\treturn nil, fmt.Errorf(\"invalid auth header\")\n\t}\n\n\t// strip off the \"Bearer \" prefix\n\tencoded := strings.TrimPrefix(authHeader, \"Bearer \")\n\n\t// decode the base64-encoded credentials\n\tbytes, err := base64.URLEncoding.DecodeString(encoded)\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error decoding auth token: %v\", err)\n\t}\n\n\t// parse the credentials\n\tvar parsed shared.AuthHeader\n\terr = json.Unmarshal(bytes, &parsed)\n\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error parsing auth token: %v\", err)\n\t}\n\n\treturn &parsed, nil\n}\n\nfunc ClearAuthCookieIfBrowser(w http.ResponseWriter, r *http.Request) error {\n\tacceptHeader := r.Header.Get(\"Accept\")\n\tif acceptHeader == \"\" {\n\t\t// no accept header, not a browser request\n\t\treturn nil","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/handlers/auth_helpers.go#L48-L84","documentation":"After stripping 'Bearer ', GetAuthHeader base64-URL-decodes the remainder; a decode failure is wrapped with this message. The token payload is expected to be base64url-encoded JSON credentials (shared.AuthHeader).","triggerScenarios":"The Authorization header's Bearer value contains characters outside the base64url alphabet (spaces, '+', '/', '=' padding from standard base64, or truncation), so base64.URLEncoding.DecodeString fails.","commonSituations":"Client uses standard base64 instead of base64url encoding, token truncated by header length limits or a copy/paste error, cookie value mangled by a proxy, or manual token construction without proper encoding.","solutions":["Re-encode the credentials with base64.URLEncoding (RawURLEncoding if no padding) on the client","Check the token wasn't truncated or altered in transit (proxy header limits, copy/paste)","If a token from another system is being reused, re-issue a token minted by this app's own auth flow","Inspect the raw Authorization header server-side and compare its length/charset with the expected token","Clear stored/cookie tokens and re-authenticate"],"exampleFix":"// before\nauthHeader := base64.StdEncoding.EncodeToString(payload) // standard base64 (+, /, =)\n// after\nauthHeader := base64.URLEncoding.EncodeToString(payload) // URL-safe alphabet","handlingStrategy":"validation","validationCode":"// client side, before sending\nif _, err := base64.URLEncoding.DecodeString(encoded); err != nil {\n    encoded = base64.URLEncoding.EncodeToString([]byte(rawPayload)) // re-encode properly\n}","typeGuard":null,"tryCatchPattern":"authHeader, err := GetAuthHeader(r)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"error decoding auth token\") { http.Error(w, \"corrupt token, please sign in again\", http.StatusUnauthorized); return }\n    http.Error(w, err.Error(), http.StatusUnauthorized)\n}","preventionTips":["Always encode auth payloads with base64.URLEncoding (not StdEncoding)","Strip whitespace/newlines from tokens before sending","Avoid tokens so long that proxies truncate headers","On decode failure client-side, discard the token and re-authenticate"],"tags":["go","auth","base64","token"],"backgroundTag":"malformed-auth-token","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}