{"record":{"id":"cd35e21036c747db","repo":"plandex-ai/plandex","slug":"no-stored-claude-credentials","errorCode":null,"errorMessage":"no stored Claude credentials","messagePattern":"no stored Claude credentials","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/claude_max.go","lineNumber":288,"sourceCode":"\t\treturn \"\", err\n\t}\n\treturn base64.RawURLEncoding.EncodeToString(buf), nil\n}\n\nfunc sha256Base64(verifier string) string {\n\tsum := sha256.Sum256([]byte(verifier))\n\treturn base64.RawURLEncoding.EncodeToString(sum[:])\n}\n\nfunc needsRefresh(creds *types.OauthCreds) bool {\n\t// refresh an hour early so we can make multiple calls before it expires\n\treturn time.Now().After(creds.ExpiresAt.Add(-1 * time.Hour))\n}\n\nfunc refreshCreds(accountCreds *types.AccountCredentials) (*types.OauthCreds, int, error) {\n\tcreds := accountCreds.ClaudeMax\n\tif creds == nil {\n\t\treturn nil, 0, fmt.Errorf(\"no stored Claude credentials\")\n\t}\n\n\tbody, err := json.Marshal(map[string]any{\n\t\t\"grant_type\":    \"refresh_token\",\n\t\t\"refresh_token\": creds.RefreshToken,\n\t\t\"client_id\":     claudeMaxClientId,\n\t})\n\tif err != nil {\n\t\treturn nil, 0, fmt.Errorf(\"refresh failed - marshal: %w\", err)\n\t}\n\n\treq, err := http.NewRequest(\"POST\", claudeMaxTokenUrl, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn nil, 0, fmt.Errorf(\"refresh failed - create request: %w\", err)\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"anthropic-beta\", shared.AnthropicClaudeMaxBetaHeader)\n","sourceCodeStart":270,"sourceCodeEnd":306,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/claude_max.go#L270-L306","documentation":"refreshCreds refreshes Claude Max OAuth tokens using the stored refresh token. Before doing anything it reads accountCreds.ClaudeMax; if no Claude Max credentials have ever been stored for the account, it returns this plain error because there is no refresh token to use.","triggerScenarios":"refreshClaudeMaxCredsIfNeeded calls refreshCreds while accountCreds.ClaudeMax is nil — i.e. the user never completed the Claude Max OAuth connect flow, or the stored credentials blob was reset/cleared.","commonSituations":"Using Claude Max features before running the OAuth connect (connectClaudeMaxOauth); credentials file created by another provider flow only; credentials wiped by a config reset, reinstall, or account switch.","solutions":["Run the Claude Max OAuth connect flow (connectClaudeMaxOauth) to obtain and store initial credentials.","Verify the credentials file/config actually contains a claudeMax section.","Check you are operating under the same account whose credentials were stored.","If credentials were lost, re-authenticate rather than retrying refresh."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"func hasClaudeMaxCreds(ac *types.AccountCredentials) bool {\n\treturn ac != nil && ac.ClaudeMax != nil && ac.ClaudeMax.RefreshToken != \"\"\n}\n// call before refresh-dependent work:\n// if !hasClaudeMaxCreds(creds) { return connectClaudeMaxOauth() }","typeGuard":"func claudeMaxCredsStored(ac *types.AccountCredentials) bool { return ac != nil && ac.ClaudeMax != nil }","tryCatchPattern":"out, n, err := refreshCreds(accountCreds)\nif err != nil {\n\tif strings.Contains(err.Error(), \"no stored Claude credentials\") {\n\t\t// fall back to interactive OAuth connect\n\t\treturn connectClaudeMaxOauth()\n\t}\n}","preventionTips":["Always run the OAuth connect flow before calling Max-specific APIs.","Persist credentials atomically so partial writes never look like 'no credentials'.","Guard refresh logic behind a stored-credentials check.","Re-authenticate after config resets rather than retrying refresh."],"tags":["go","oauth","credentials","claude-max"],"backgroundTag":"missing-oauth-credentials","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"}