{"record":{"id":"cbf38ae57f5b9309","repo":"plandex-ai/plandex","slug":"refresh-failed-create-request-w","errorCode":null,"errorMessage":"refresh failed - create request: %w","messagePattern":"refresh failed - create request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/claude_max.go","lineNumber":302,"sourceCode":"\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\n\tresp, err := http.DefaultClient.Do(req)\n\tif err != nil {\n\t\treturn nil, 0, fmt.Errorf(\"refresh failed - http: %w\", err)\n\t}\n\tdefer resp.Body.Close()\n\n\tif resp.StatusCode != http.StatusOK {\n\t\tb, err := io.ReadAll(resp.Body)\n\t\tif err != nil {\n\t\t\treturn nil, 0, fmt.Errorf(\"refresh failed - read body: %w\", err)\n\t\t}\n\t\treturn nil, resp.StatusCode, fmt.Errorf(\"refresh failed - status %d: %s\", resp.StatusCode, b)\n\t}\n","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/claude_max.go#L284-L320","documentation":"refreshCreds in claude_max.go wraps an error returned by http.NewRequest when building the OAuth token refresh POST to claudeMaxTokenUrl. http.NewRequest only fails on an invalid URL, an unsupported HTTP method, or a malformed body, so this indicates the token endpoint URL constant is structurally broken rather than a network problem.","triggerScenarios":"http.NewRequest(\"POST\", claudeMaxTokenUrl, bytes.NewReader(body)) returns a non-nil error — typically because claudeMaxTokenUrl fails url.Parse (malformed or empty URL), or the request body implements io.Reader incorrectly.","commonSituations":"A build-time misconfiguration or recent change of the claudeMaxTokenUrl constant (empty string, missing scheme, control characters), or a compiled-in default overwritten by a bad config/env value used to construct the URL.","solutions":["Inspect the claudeMaxTokenUrl constant and any config/env value feeding it; verify it is a valid absolute URL (e.g. https://...).","Log the exact URL string in the error path to see what is being parsed.","Add a startup validation (url.Parse) that fails fast if the token URL is empty or unparsable.","If the body is custom, confirm its Read method never returns an unsupported error type."],"exampleFix":"// before\nconst claudeMaxTokenUrl = \"\"\n// after\nconst claudeMaxTokenUrl = \"https://api.anthropic.com/oauth/token\" // valid absolute URL\n// fail fast at startup\nu, err := url.Parse(claudeMaxTokenUrl)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    panic(\"invalid claudeMaxTokenUrl\")\n}","handlingStrategy":"validation","validationCode":"u, err := url.Parse(claudeMaxTokenUrl)\nif err != nil || u.Scheme == \"\" || u.Host == \"\" {\n    return fmt.Errorf(\"invalid token URL %q: %w\", claudeMaxTokenUrl, err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the token URL as a compile-time constant with a valid absolute URL.","Validate the URL with url.Parse at startup, not at request time.","Never construct the URL from unsanitized user/env input without validation."],"tags":["http","oauth","request-construction","configuration"],"backgroundTag":"invalid-request-url","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"}