chenhg5/cc-connect · error
read %s: %w
Error message
read %s: %w
What it means
readOAuthTokens loads Codex CLI OAuth credentials from ~/.codex/auth.json (or $CODEX_HOME/auth.json) to authenticate usage-quota queries against the ChatGPT backend. This error wraps the underlying os.ReadFile failure, preserving the file path and OS-level cause (e.g. ENOENT, EACCES). It is thrown whenever the auth.json file cannot be read, which the library treats as a hard failure because usage data cannot be fetched without a token.
Source
Thrown at agent/codex/usage.go:68
Balance any `json:"balance"`
}
func (a *Agent) GetUsage(ctx context.Context) (*core.UsageReport, error) {
tokens, err := a.readOAuthTokens(os.ReadFile)
if err != nil {
return nil, err
}
return a.fetchUsage(ctx, http.DefaultClient, tokens)
}
func (a *Agent) readOAuthTokens(readFile func(string) ([]byte, error)) (codexOAuthTokens, error) {
path, err := codexAuthPath()
if err != nil {
return codexOAuthTokens{}, err
}
data, err := readFile(path)
if err != nil {
return codexOAuthTokens{}, fmt.Errorf("read %s: %w", path, err)
}
var payload struct {
Tokens struct {
AccessToken string `json:"access_token"`
AccountID string `json:"account_id"`
} `json:"tokens"`
}
if err := json.Unmarshal(data, &payload); err != nil {
return codexOAuthTokens{}, fmt.Errorf("parse auth.json: %w", err)
}
if strings.TrimSpace(payload.Tokens.AccessToken) == "" {
return codexOAuthTokens{}, fmt.Errorf("auth.json missing tokens.access_token")
}
if strings.TrimSpace(payload.Tokens.AccountID) == "" {
return codexOAuthTokens{}, fmt.Errorf("auth.json missing tokens.account_id")
}
View on GitHub (pinned to 4000b2338a)
Solutions
- Run `codex login` to create the auth.json file
- Verify the resolved path: check CODEX_HOME, or confirm ~/.codex/auth.json exists (`ls -la $CODEX_HOME/auth.json` or `ls -la ~/.codex/auth.json`)
- If running as a daemon/service, set CODEX_HOME (or HOME) to the directory containing the logged-in auth.json
- Fix file permissions so the process user can read auth.json (chmod 600, correct owner)
Example fix
// before: error only visible at runtime
usage, err := agent.GetUsage(ctx)
// after: probe the auth file first and give a clear message
if _, err := os.Stat(filepath.Join(os.Getenv("CODEX_HOME"), "auth.json")); os.IsNotExist(err) {
log.Fatal("codex auth.json not found; run `codex login` first")
}
usage, err := agent.GetUsage(ctx) Defensive patterns
Strategy: validation
Validate before calling
p := filepath.Join(os.Getenv("CODEX_HOME"), "auth.json")
if os.Getenv("CODEX_HOME") == "" { p = filepath.Join(os.Getenv("HOME"), ".codex", "auth.json") }
if _, err := os.Stat(p); err != nil { return fmt.Errorf("codex auth.json not readable at %s: %w", p, err) } Try / catch
tokens, err := readOAuthTokens()
if err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrNotExist) {
return fmt.Errorf("run `codex login` first (missing %s)", pe.Path)
}
return err
} Prevention
- Run `codex login` before enabling usage queries
- Set CODEX_HOME explicitly in daemon/service environments
- Ensure the service runs as the user owning ~/.codex
- Add a startup health check that stats auth.json
When it happens
Trigger: GetUsage() -> readOAuthTokens() when readFile(path) fails: the auth.json path does not exist (Codex never logged in), the path is a directory, or the file cannot be opened due to permissions. Callers: GetUsage and the readOAuthTokens tests.
Common situations: Running usage queries on a machine where `codex login` was never executed; CODEX_HOME pointing at a nonexistent or wrong directory; running the bridge under a service account (systemd/launchd) whose HOME differs from the user that logged into Codex; restrictive file permissions after copying dotfiles.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- parse auth.json: %w
- auth.json missing tokens.access_token
- auth.json missing tokens.account_id
- create Agy permission overlay: %w
- read existing Agy hooks %s: %w
AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06).
Data as JSON: /api/errors/41652e96263a9465.
Report an issue: GitHub.