Client or integration
Codex CLI
Area
Authentication and account pool
Summary
__main__(native ~/.codex/auth.json) 계정의 자격증명이 무효가 되어도 관리 API와 대시보드가 그 사실을 전혀 표시하지 않습니다. pool 계정은 needsReauth 필드로 상태를 알 수 있지만, __main__은 해당 필드 자체가 DTO에 없고 실패 시 plan: null, quota: null만 남습니다. 이 값은 "아직 quota prime이 안 된 정상 계정"과 구분되지 않습니다.
codexAccountMode: pool에서 __main__은 rotation에 참여하므로(codex/routing.ts:256-262), 무효한 main이 선택되면 요청이 upstream 403으로 실패합니다. 그런데 대시보드에는 아무 이상 신호가 없어서 원인을 찾기가 어렵습니다.
기대 동작: __main__도 pool 계정과 동일하게 헬스 상태(needsReauth 또는 이에 준하는 오류 표시)를 노출해야 합니다.
Reproduction
~/.codex/auth.json을 무효한 ChatGPT 토큰으로 만듭니다. (재현에 사용한 상태: 토큰에 박힌 workspace가 더 이상 선택 불가여서 upstream이 403 {"detail":{"code":"invalid_workspace_selected"}}를 반환, refresh token도 401 invalid_refresh_token)
- pool에는 정상 OAuth 계정을 여러 개 등록해 둡니다.
curl -s http://127.0.0.1:10100/api/codex-auth/accounts 를 호출합니다.
- 결과에서
__main__ 항목이 아래처럼 나옵니다. pool 계정에는 needsReauth: false가 있지만 __main__에는 상태를 나타내는 필드가 없습니다.
{ "id": "__main__", "email": "Codex App login", "plan": null,
"isMain": true, "hasCredential": true, "quota": null }
?refresh=1을 붙여 강제 갱신해도 동일합니다. 대시보드에서도 main 계정은 정상 항목과 동일하게 보입니다.
관련 코드 두 곳으로 보입니다.
src/codex/auth-api.ts listCodexAuthAccounts() — main DTO를 만들 때 needsReauth를 넣지 않습니다. pool 쪽 poolAccountDto()에는 포함됩니다.
src/codex/auth-api.ts fetchMainAccountInfo() — if (!resp.ok) return { email: null, plan: null, quota: null } 로 처리해서, wham/usage가 돌려준 401/403(= 자격증명이 죽었다는 강한 신호)을 그대로 버립니다. 이 시점에 markAccountNeedsReauth(MAIN_CODEX_ACCOUNT_ID)를 하지 않습니다.
isCodexAccountUsable()와 routing.ts는 이미 isAccountNeedsReauth(MAIN_CODEX_ACCOUNT_ID)를 확인하고 있어서, 상태를 세팅·노출하는 경로만 보완되면 기존 rotation 로직과 자연스럽게 맞물릴 것으로 보입니다.
제안:
fetchMainAccountInfo()에서 401/403이면 markAccountNeedsReauth(MAIN_CODEX_ACCOUNT_ID) 호출
- main DTO에도
needsReauth(또는 마지막 실패 상태) 필드 추가
Version
@bitkyc08/opencodex: 2.7.33
@openai/codex: 0.145.0
Operating system
Ubuntu 24.04.4 LTS (x86_64, WSL2) — 동일 증상을 Ubuntu 서버 3대, Oracle Linux aarch64 1대에서도 확인
Provider and model
- Provider:
openai (ChatGPT 백엔드, authMode: forward)
- Model:
gpt-5.5, gpt-5.6-terra
Logs or error output
# 1) main 토큰으로 upstream 직접 호출
$ POST https://chatgpt.com/backend-api/codex/responses
403 {"detail":{"code":"invalid_workspace_selected"}}
# 2) main refresh token
$ POST https://auth.openai.com/oauth/token (grant_type=refresh_token)
401 {"error":{"code":"invalid_refresh_token","message":"Invalid refresh token."}}
# 3) 같은 시점 관리 API — main 계정에 이상 신호 없음
$ curl -s http://127.0.0.1:10100/api/codex-auth/accounts
[('__main__', '<masked>', None, None),
('<pool-1>', '<masked>', 'team', False),
('<pool-2>', '<masked>', 'team', False),
('<pool-3>', '<masked>', 'team', False)]
# 튜플 = (id, email, plan, needsReauth)
# 계정 id/email은 마스킹했습니다. 핵심은 pool 계정에는 needsReauth가 있고
# __main__에는 그 자리에 아무 상태 필드도 없다는 점입니다.
참고
#320 과 주제는 인접하지만 다른 지점이라고 생각합니다. #320은 native auth가 만료됐을 때 Codex CLI가 로그인창을 여는 동작에 대한 것이고, 이 이슈는 OpenCodex 자신의 계정 목록 API/대시보드가 __main__의 무효 상태를 표시하지 않는다는 관측성 문제입니다. 중복이라고 판단되시면 닫아주셔도 괜찮습니다.
Client or integration
Codex CLI
Area
Authentication and account pool
Summary
__main__(native~/.codex/auth.json) 계정의 자격증명이 무효가 되어도 관리 API와 대시보드가 그 사실을 전혀 표시하지 않습니다. pool 계정은needsReauth필드로 상태를 알 수 있지만,__main__은 해당 필드 자체가 DTO에 없고 실패 시plan: null, quota: null만 남습니다. 이 값은 "아직 quota prime이 안 된 정상 계정"과 구분되지 않습니다.codexAccountMode: pool에서__main__은 rotation에 참여하므로(codex/routing.ts:256-262), 무효한 main이 선택되면 요청이 upstream 403으로 실패합니다. 그런데 대시보드에는 아무 이상 신호가 없어서 원인을 찾기가 어렵습니다.기대 동작:
__main__도 pool 계정과 동일하게 헬스 상태(needsReauth또는 이에 준하는 오류 표시)를 노출해야 합니다.Reproduction
~/.codex/auth.json을 무효한 ChatGPT 토큰으로 만듭니다. (재현에 사용한 상태: 토큰에 박힌 workspace가 더 이상 선택 불가여서 upstream이403 {"detail":{"code":"invalid_workspace_selected"}}를 반환, refresh token도401 invalid_refresh_token)curl -s http://127.0.0.1:10100/api/codex-auth/accounts를 호출합니다.__main__항목이 아래처럼 나옵니다. pool 계정에는needsReauth: false가 있지만__main__에는 상태를 나타내는 필드가 없습니다.{ "id": "__main__", "email": "Codex App login", "plan": null, "isMain": true, "hasCredential": true, "quota": null }?refresh=1을 붙여 강제 갱신해도 동일합니다. 대시보드에서도 main 계정은 정상 항목과 동일하게 보입니다.관련 코드 두 곳으로 보입니다.
src/codex/auth-api.tslistCodexAuthAccounts()— main DTO를 만들 때needsReauth를 넣지 않습니다. pool 쪽poolAccountDto()에는 포함됩니다.src/codex/auth-api.tsfetchMainAccountInfo()—if (!resp.ok) return { email: null, plan: null, quota: null }로 처리해서,wham/usage가 돌려준 401/403(= 자격증명이 죽었다는 강한 신호)을 그대로 버립니다. 이 시점에markAccountNeedsReauth(MAIN_CODEX_ACCOUNT_ID)를 하지 않습니다.isCodexAccountUsable()와routing.ts는 이미isAccountNeedsReauth(MAIN_CODEX_ACCOUNT_ID)를 확인하고 있어서, 상태를 세팅·노출하는 경로만 보완되면 기존 rotation 로직과 자연스럽게 맞물릴 것으로 보입니다.제안:
fetchMainAccountInfo()에서 401/403이면markAccountNeedsReauth(MAIN_CODEX_ACCOUNT_ID)호출needsReauth(또는 마지막 실패 상태) 필드 추가Version
@bitkyc08/opencodex: 2.7.33@openai/codex: 0.145.0Operating system
Ubuntu 24.04.4 LTS (x86_64, WSL2) — 동일 증상을 Ubuntu 서버 3대, Oracle Linux aarch64 1대에서도 확인
Provider and model
openai(ChatGPT 백엔드,authMode: forward)gpt-5.5,gpt-5.6-terraLogs or error output
참고
#320 과 주제는 인접하지만 다른 지점이라고 생각합니다. #320은 native auth가 만료됐을 때 Codex CLI가 로그인창을 여는 동작에 대한 것이고, 이 이슈는 OpenCodex 자신의 계정 목록 API/대시보드가
__main__의 무효 상태를 표시하지 않는다는 관측성 문제입니다. 중복이라고 판단되시면 닫아주셔도 괜찮습니다.