From abd58247c04b38ed0633ce4f33a2f85d91bdb7e1 Mon Sep 17 00:00:00 2001 From: Agents Agent Date: Sat, 27 Jun 2026 15:23:22 +0200 Subject: [PATCH] =?UTF-8?q?fix(agents-login):=20codex=20config.toml=20is?= =?UTF-8?q?=20optional=20=E2=80=94=20fixes=20ENOENT=20after=20entering=20t?= =?UTF-8?q?he=20device=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `codex login --device-auth` writes auth.json but NOT config.toml, so captureCodex's readUtf8(config.toml) threw "ENOENT ... /home/agent/.codex/config.toml" right after the user entered their code, failing the whole sign-in. Read config.toml with readUtf8OrUndefined and include it only when present; payloadForApi requires only auth_json. (agents-api now accepts an auth_json-only codex credential and the runner self-provisions a config.toml.) Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/worker/agentsApiClient.ts | 5 +++-- .../agents-login/src/worker/credentials.ts | 21 +++++++++++-------- .../agents-login/test/agentsApiClient.test.ts | 7 ++++++- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/services/agents-login/src/worker/agentsApiClient.ts b/services/agents-login/src/worker/agentsApiClient.ts index 30b854aa..9f047b0f 100644 --- a/services/agents-login/src/worker/agentsApiClient.ts +++ b/services/agents-login/src/worker/agentsApiClient.ts @@ -88,10 +88,11 @@ export function payloadForApi(provider: Provider, bundle: CredentialBundle): Rec const authJson = bundle.data.auth_json const configToml = bundle.data.config_toml - if (!authJson || !configToml) { + if (!authJson) { throw new Error('no Codex credential captured') } - return { auth_json: authJson, config_toml: configToml } + // config_toml is optional (codex login does not write it); include when present. + return { auth_json: authJson, ...(configToml ? { config_toml: configToml } : {}) } } async function safeText(res: Response): Promise { diff --git a/services/agents-login/src/worker/credentials.ts b/services/agents-login/src/worker/credentials.ts index 9cd925dc..196119c4 100644 --- a/services/agents-login/src/worker/credentials.ts +++ b/services/agents-login/src/worker/credentials.ts @@ -146,16 +146,19 @@ export async function captureCodex( ): Promise { const authPath = join(paths.codexHome, 'auth.json') const configPath = join(paths.codexHome, 'config.toml') - const [auth, config] = await Promise.all([readUtf8(authPath), readUtf8(configPath)]) - return { - data: { - auth_json: auth, - config_toml: config, - schema_version: SCHEMA_VERSION, - updated_at: now().toISOString(), - updated_by: updatedBy, - }, + // `codex login` writes auth.json (the credential) but NOT config.toml, so + // config.toml is optional — requiring it threw ENOENT and broke sign-in. + const [auth, config] = await Promise.all([readUtf8(authPath), readUtf8OrUndefined(configPath)]) + const data: Record = { + auth_json: auth, + schema_version: SCHEMA_VERSION, + updated_at: now().toISOString(), + updated_by: updatedBy, + } + if (config !== undefined) { + data.config_toml = config } + return { data } } export async function capture( diff --git a/services/agents-login/test/agentsApiClient.test.ts b/services/agents-login/test/agentsApiClient.test.ts index 85a48aa7..155c79f6 100644 --- a/services/agents-login/test/agentsApiClient.test.ts +++ b/services/agents-login/test/agentsApiClient.test.ts @@ -120,7 +120,12 @@ describe('AgentsApiClient', () => { it('rejects incomplete provider payloads before posting', () => { expect(() => payloadForApi('claude', { data: { account_json: '{}' } })).toThrow(/Claude credentials_json/) - expect(() => payloadForApi('codex', { data: { auth_json: '{}' } })).toThrow(/Codex credential/) + // Codex requires auth_json; config_toml is optional (codex login never writes it). + expect(() => payloadForApi('codex', { data: { config_toml: 'x = 1' } })).toThrow(/Codex credential/) + }) + + it('posts a codex payload with auth_json alone (config_toml optional)', () => { + expect(payloadForApi('codex', { data: { auth_json: '{"tokens":"t"}' } })).toEqual({ auth_json: '{"tokens":"t"}' }) }) it('reports only unknown local stored status', () => {