Skip to content

Commit 5cff88a

Browse files
committed
fix(init): debug log whoami fallback
1 parent 3305dfa commit 5cff88a

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

src/commands/init.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,45 @@ describe('runInit — happy path (interactive)', () => {
231231
expect(agent.skills).toContain('testsprite-verify');
232232
expect(agent.skills).toContain('testsprite-onboard');
233233
});
234+
235+
it('debug mode reports a display-only whoami lookup failure without corrupting JSON stdout', async () => {
236+
const { captured, deps } = makeCapture();
237+
let callCount = 0;
238+
const fetchMock = vi.fn(async () => {
239+
callCount += 1;
240+
if (callCount === 1) {
241+
return new Response(JSON.stringify(ME), {
242+
status: 200,
243+
headers: { 'content-type': 'application/json' },
244+
});
245+
}
246+
return new Response(
247+
JSON.stringify({
248+
error: {
249+
code: 'AUTH_INVALID',
250+
message: 'Invalid API key',
251+
nextAction: 'Provide a valid key.',
252+
requestId: 'r-whoami',
253+
},
254+
}),
255+
{ status: 401, headers: { 'content-type': 'application/json' } },
256+
);
257+
}) as unknown as InitDeps['fetchImpl'];
258+
259+
await runInit(
260+
makeBaseOpts({ apiKey: 'sk-json-test', debug: true, noAgent: true, output: 'json' }),
261+
{
262+
...deps,
263+
fetchImpl: fetchMock,
264+
credentialsPath,
265+
isTTY: false,
266+
},
267+
);
268+
269+
const parsed = JSON.parse(captured.stdout.join('\n')) as Record<string, unknown>;
270+
expect(parsed.status).toBe('initialized');
271+
expect(captured.stderr.some(line => line.includes('setup identity lookup failed'))).toBe(true);
272+
});
234273
});
235274

236275
// ---------------------------------------------------------------------------

src/commands/init.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,9 +291,13 @@ export async function runInit(opts: InitOptions, deps: InitDeps = {}): Promise<v
291291
let me: MeResponse;
292292
try {
293293
me = await runWhoami(opts, whoamiDeps);
294-
} catch {
294+
} catch (err) {
295295
// Whoami is display-only. If it fails after a successful configure,
296296
// continue with a minimal placeholder so the summary still prints.
297+
if (opts.debug) {
298+
const reason = err instanceof Error ? err.message : String(err);
299+
stderrFn(`[debug] setup identity lookup failed after configure: ${reason}`);
300+
}
297301
me = { userId: '', keyId: '', scopes: [], env: 'production' };
298302
}
299303

0 commit comments

Comments
 (0)