jackwener/OpenCLI · error · CommandExecutionError
Claude whoami failed: ${result.detail}
Error message
Claude whoami failed: ${result.detail} What it means
This CommandExecutionError wraps any JavaScript exception thrown inside the in-page fetch probe to /api/organizations (the caught error is stringified into result.detail). It indicates the whoami verification script itself crashed in the browser context rather than receiving a normal HTTP response — e.g. a failed fetch (network/DNS error), JSON parsing failure, or a Claude page change that breaks the script.
Source
Thrown at clis/claude/auth.js:36
if (res.status === 401 || res.status === 403) {
return { kind: 'auth', detail: 'Claude /api/organizations HTTP ' + res.status };
}
if (!res.ok) return { kind: 'http', httpStatus: res.status };
const d = await res.json();
if (!Array.isArray(d) || d.length === 0) {
return { kind: 'auth', detail: 'Claude /api/organizations empty' };
}
const userIdCookie = (document.cookie.split('; ').find(c => c.startsWith('ajs_user_id=')) || '').split('=')[1] || '';
const activeOrgCookie = (document.cookie.split('; ').find(c => c.startsWith('lastActiveOrg=')) || '').split('=')[1] || '';
const activeOrg = d.find(o => o.uuid === activeOrgCookie) || d[0];
return { ok: true, user_id: userIdCookie, org_name: activeOrg.name || '', org_uuid: activeOrg.uuid || '' };
} catch (e) {
return { kind: 'exception', detail: String(e && e.message || e) };
}
})()`);
if (result?.kind === 'auth') throw new AuthRequiredError('claude.ai', result.detail);
if (result?.kind === 'http') throw new CommandExecutionError(`HTTP ${result.httpStatus} from /api/organizations`);
if (result?.kind === 'exception') throw new CommandExecutionError(`Claude whoami failed: ${result.detail}`);
if (!result?.ok) throw new CommandExecutionError(`Unexpected Claude probe: ${JSON.stringify(result)}`);
if (!result.user_id) throw new AuthRequiredError('claude.ai', 'Claude session incomplete — ajs_user_id cookie missing');
return { user_id: String(result.user_id), org_name: String(result.org_name), org_uuid: String(result.org_uuid) };
}
registerSiteAuthCommands({
site: 'claude',
domain: 'claude.ai',
loginUrl: 'https://claude.ai/login',
columns: ['user_id', 'org_name', 'org_uuid'],
quickCheck: hasClaudeSessionCookie,
verify: verifyClaudeIdentity,
poll: async (page) => {
if (!await hasClaudeSessionCookie(page)) {
throw new AuthRequiredError('claude.ai', 'Waiting for Claude sessionKey cookie');
}
return verifyClaudeIdentity(page);
},View on GitHub (pinned to 49907e53dc)
Solutions
- Read result.detail in the message to see the underlying exception and address it specifically
- Verify general internet connectivity and that https://claude.ai loads in the browser without a Cloudflare challenge
- Disable conflicting extensions (ad-blockers/script blockers) or bypass VPN/proxy, then retry
- Re-run the login flow (`opencli claude auth`) so the probe runs on a freshly loaded claude.ai page
- Update the library — Claude may have changed its response format and a newer probe handles it
Example fix
// before
const res = await fetch('/api/organizations', { credentials: 'include' }); // TypeError: Failed to fetch (offline)
// after
// ensure connectivity first, then retry:
ping claude.ai && opencli claude whoami Defensive patterns
Strategy: try-catch
Validate before calling
// ensure connectivity before running browser probes
const res = await fetch('https://claude.ai/robots.txt').catch(() => null);
if (!res || !res.ok) throw new Error('claude.ai unreachable — check network/VPN/proxy'); Type guard
function isProbeException(result) {
return !!result && result.kind === 'exception' && typeof result.detail === 'string';
} Try / catch
try {
const identity = await verifyClaudeIdentity(page);
} catch (e) {
if (e.message.startsWith('Claude whoami failed:')) {
console.error('Probe crashed in page:', e.message);
// check network, disable interfering extensions, reload page and retry once
}
throw e;
} Prevention
- Verify network/VPN/proxy access to claude.ai before automation runs
- Disable ad-blocker/script-blocker extensions in the automation browser profile
- Re-run the auth flow so the probe executes on a freshly loaded page
- Update the library when Claude changes its response format
When it happens
Trigger: The page.evaluate probe's try block throws: network failure reaching /api/organizations (offline, DNS failure, proxy block), res.json() failing on a non-JSON response (login redirect HTML, Cloudflare challenge page), or an injected script/CSP change breaking evaluation.
Common situations: Corporate proxy or VPN blocking claude.ai API calls; Cloudflare interstitial returning HTML so JSON parsing throws; internet drop mid-probe; browser extension or CSP changes blocking in-page fetch; Claude frontend returning an unexpected payload shape after an update.
Related errors
- Jike identity probe failed: ${probe.detail}
- Midjourney browser-context media fetch failed: ${errorMessag
- Twitter device-follow fetch failed: ${data.detail || 'unknow
- Zhihu answer detail request failed: ${err instanceof Error ?
- Batch fetch failed for ${urls[i]}: ${(r as { error: string }
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/ef5e3f0376fc9401.
Report an issue: GitHub.