{"record":{"id":"fccff57b34017de0","repo":"chenhg5/cc-connect","slug":"auth-json-missing-tokens-access-token","errorCode":null,"errorMessage":"auth.json missing tokens.access_token","messagePattern":"auth\\.json missing tokens\\.access_token","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agent/codex/usage.go","lineNumber":81,"sourceCode":"\tif err != nil {\n\t\treturn codexOAuthTokens{}, err\n\t}\n\tdata, err := readFile(path)\n\tif err != nil {\n\t\treturn codexOAuthTokens{}, fmt.Errorf(\"read %s: %w\", path, err)\n\t}\n\n\tvar payload struct {\n\t\tTokens struct {\n\t\t\tAccessToken string `json:\"access_token\"`\n\t\t\tAccountID   string `json:\"account_id\"`\n\t\t} `json:\"tokens\"`\n\t}\n\tif err := json.Unmarshal(data, &payload); err != nil {\n\t\treturn codexOAuthTokens{}, fmt.Errorf(\"parse auth.json: %w\", err)\n\t}\n\tif strings.TrimSpace(payload.Tokens.AccessToken) == \"\" {\n\t\treturn codexOAuthTokens{}, fmt.Errorf(\"auth.json missing tokens.access_token\")\n\t}\n\tif strings.TrimSpace(payload.Tokens.AccountID) == \"\" {\n\t\treturn codexOAuthTokens{}, fmt.Errorf(\"auth.json missing tokens.account_id\")\n\t}\n\n\treturn codexOAuthTokens{\n\t\tAccessToken: payload.Tokens.AccessToken,\n\t\tAccountID:   payload.Tokens.AccountID,\n\t}, nil\n}\n\nfunc (a *Agent) fetchUsage(ctx context.Context, client *http.Client, tokens codexOAuthTokens) (*core.UsageReport, error) {\n\treq, err := http.NewRequestWithContext(ctx, http.MethodGet, codexUsageURL, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treq.Header.Set(\"Authorization\", \"Bearer \"+tokens.AccessToken)\n\treq.Header.Set(\"ChatGPT-Account-Id\", tokens.AccountID)","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/agent/codex/usage.go#L63-L99","documentation":"readOAuthTokens validates that the parsed auth.json contains a non-empty tokens.access_token. This error is thrown when the JSON parses fine but the access_token field is absent, empty, or whitespace-only. Without an access token the usage endpoint cannot be called, so the library fails fast with this explicit message.","triggerScenarios":"json.Unmarshal succeeds but strings.TrimSpace(payload.Tokens.AccessToken) == \"\" — auth.json has a tokens object without access_token, or with \"\"/null. Detected by TestReadOAuthTokens_MissingFields and surfaced via GetUsage.","commonSituations":"Partially completed Codex login (tokens object written before access token stored); hand-crafted or copy-pasted auth.json missing the field; Codex CLI version change that altered the auth.json schema; token cleared by a logout that left an empty structure.","solutions":["Run `codex login` again to obtain a fresh access token","Inspect auth.json and confirm tokens.access_token is present and non-empty","If auth.json was hand-copied, copy the complete file from a properly logged-in machine","Check whether a logout/credential-cleanup job wiped the token and re-authenticate"],"exampleFix":"// before: assumes token exists\nusage, err := agent.GetUsage(ctx)\n// after: verify the field before calling\nvar a struct{ Tokens struct{ AccessToken string `json:\"access_token\"` } `json:\"tokens\"` }\nif json.Unmarshal(authBytes, &a) == nil && strings.TrimSpace(a.Tokens.AccessToken) == \"\" {\n    log.Fatal(\"auth.json lacks tokens.access_token; run `codex login`\")\n}\nusage, err := agent.GetUsage(ctx)","handlingStrategy":"validation","validationCode":"var a struct{ Tokens struct{ AccessToken string `json:\"access_token\"` } `json:\"tokens\"` }\njson.Unmarshal(b, &a)\nif strings.TrimSpace(a.Tokens.AccessToken) == \"\" { return errors.New(\"missing tokens.access_token; run `codex login`\") }","typeGuard":null,"tryCatchPattern":"if _, err := agent.GetUsage(ctx); err != nil && strings.Contains(err.Error(), \"missing tokens.access_token\") {\n    log.Println(\"Codex token missing — trigger `codex login` re-auth\")\n}","preventionTips":["Re-run `codex login` after any logout or credential cleanup","Copy the complete auth.json, not a reconstructed subset","Upgrade Codex CLI if your auth.json schema predates access_token","Alert on empty token fields during config validation"],"tags":["go","codex","oauth","validation"],"backgroundTag":"empty-required-field","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}