{"record":{"id":"58fdfad9443855eb","repo":"plandex-ai/plandex","slug":"error-marshalling-auth-header-v","errorCode":null,"errorMessage":"error marshalling auth header: %v","messagePattern":"error marshalling auth header: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/auth/api.go","lineNumber":35,"sourceCode":"\tapiClient = client\n}\n\nfunc SetAuthHeader(req *http.Request) error {\n\tif Current == nil {\n\t\treturn fmt.Errorf(\"error setting auth header: auth not loaded\")\n\t}\n\thash := Current.ToHash()\n\n\tauthHeader := shared.AuthHeader{\n\t\tToken: Current.Token,\n\t\tOrgId: Current.OrgId,\n\t\tHash:  hash,\n\t}\n\n\tbytes, err := json.Marshal(authHeader)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error marshalling auth header: %v\", err)\n\t}\n\n\t// base64 encode\n\ttoken := base64.URLEncoding.EncodeToString(bytes)\n\n\treq.Header.Set(\"Authorization\", \"Bearer \"+token)\n\n\treturn nil\n}\n\nfunc SetVersionHeader(req *http.Request) {\n\treq.Header.Set(\"X-Client-Version\", version.Version)\n}\n","sourceCodeStart":17,"sourceCodeEnd":49,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/auth/api.go#L17-L49","documentation":"After building a shared.AuthHeader from the loaded auth, SetAuthHeader marshals it to JSON. This error wraps any failure from json.Marshal on that struct. In practice this is nearly impossible for the plain AuthHeader struct, so it almost always indicates a corrupted or hostile in-memory auth state rather than user configuration.","triggerScenarios":"json.Marshal(authHeader) returns an error — realistically only if unsupported values (channels, funcs, cycles) were injected into the auth struct, since all AuthHeader fields are JSON-encodable primitives.","commonSituations":"Memory corruption or a modified build of plandex-shared that added non-serializable fields to AuthHeader; custom middleware mutating the request context; essentially never seen in normal usage.","solutions":["Rebuild with the stock plandex-shared version to ensure AuthHeader contains only serializable fields","Re-authenticate to regenerate Current from a fresh sign-in","Report as a bug with the wrapped inner error (%v) if reproducible"],"exampleFix":"// before\nbytes, err := json.Marshal(authHeader)\nif err != nil { return fmt.Errorf(\"error marshalling auth header: %v\", err) }\n// after\nbytes, err := json.Marshal(shared.AuthHeader{Token: Current.Token, OrgId: Current.OrgId, Hash: Current.ToHash()})\nif err != nil { return fmt.Errorf(\"error marshalling auth header: %v (token=%d bytes org=%s)\", err, len(Current.Token), Current.OrgId) }","handlingStrategy":"try-catch","validationCode":"if auth.Current == nil || auth.Current.Token == \"\" {\n\treturn fmt.Errorf(\"no valid auth to marshal\")\n}","typeGuard":"func marshalableAuth(a *shared.ClientAuth) bool { return a != nil && json.Valid([]byte(fmt.Sprintf(\"%v\", a.Token))) }","tryCatchPattern":"if err := auth.SetAuthHeader(req); err != nil {\n\tif strings.Contains(err.Error(), \"marshalling\") {\n\t\t// treat as corrupt auth state: re-authenticate\n\t\tauth.MustResolveAuth(false)\n\t\treturn auth.SetAuthHeader(req)\n\t}\n\treturn err\n}","preventionTips":["Keep plandex-shared at the version matching the CLI so AuthHeader stays plain serializable","Never mutate shared.AuthHeader or ClientAuth with non-JSON-encodable values","Re-authenticate rather than hand-editing auth state in memory","Log the inner wrapped error verbatim when reporting bugs"],"tags":["json","serialization","auth"],"backgroundTag":"json-marshal-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}