jackwener/OpenCLI · error · CommandExecutionError
LinkedIn Learning whoami failed: ${result.detail}
Error message
LinkedIn Learning whoami failed: ${result.detail} What it means
The whoami probe wraps its page-side logic in try/catch and reports failures as { kind:'exception', detail }; the command surfaces this as CommandExecutionError 'LinkedIn Learning whoami failed: <detail>'. It means the page-side JavaScript itself threw (network failure inside the page, undefined variable, JSON parsing issue) rather than returning an auth/http verdict.
Source
Thrown at clis/linkedin-learning/auth.js:44
const mini = d && d.miniProfile;
if (!mini || !mini.publicIdentifier) {
return { kind: 'auth', detail: 'LinkedIn /voyager/api/me 200 but miniProfile missing' };
}
const firstName = (mini.firstName && (mini.firstName.text || mini.firstName)) || '';
const lastName = (mini.lastName && (mini.lastName.text || mini.lastName)) || '';
return {
ok: true,
public_id: String(mini.publicIdentifier),
plain_id: String(d.plainId || ''),
name: String((firstName + ' ' + lastName).trim()),
};
} catch (e) {
return { kind: 'exception', detail: String(e && e.message || e) };
}
})()`);
if (result?.kind === 'auth') throw new AuthRequiredError('linkedin.com', result.detail);
if (result?.kind === 'http') throw new CommandExecutionError(`HTTP ${result.httpStatus} from /voyager/api/me`);
if (result?.kind === 'exception') throw new CommandExecutionError(`LinkedIn Learning whoami failed: ${result.detail}`);
if (!result?.ok) throw new CommandExecutionError(`Unexpected LinkedIn Learning probe: ${JSON.stringify(result)}`);
return { public_id: result.public_id, plain_id: result.plain_id, name: result.name };
}
registerSiteAuthCommands({
site: 'linkedin-learning',
domain: 'linkedin.com',
loginUrl: 'https://www.linkedin.com/login?session_redirect=%2Flearning%2F',
columns: ['public_id', 'plain_id', 'name'],
quickCheck: hasLinkedinSessionCookie,
verify: verifyLinkedinLearningIdentity,
poll: async (page) => {
if (!await hasLinkedinSessionCookie(page)) {
throw new AuthRequiredError('linkedin.com', 'Waiting for LinkedIn li_at cookie');
}
return verifyLinkedinLearningIdentity(page);
},
});View on GitHub (pinned to 49907e53dc)
Solutions
- Read result.detail in the error message to identify the underlying exception (TypeError vs network failure).
- Re-run after reloading the LinkedIn Learning page — transient in-page fetch failures resolve on retry.
- If it's a shape change, update the probe to defensively read the new /voyager/api/me response structure.
- Verify the page is actually on linkedin.com (not an error/interstitial page) before probing.
Example fix
// before
const included = json.included[0]; // throws when shape changes
// after
const included = json?.included?.[0];
if (!included) return { kind: 'auth', detail: 'unexpected /voyager/api/me shape' }; Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure we are on a real LinkedIn Learning page before evaluating
if (!page.url().includes('linkedin.com/learning')) await page.goto('https://www.linkedin.com/learning/'); Type guard
function isExceptionKindResult(r) { return r?.kind === 'exception' && typeof r.detail === 'string'; } Try / catch
try {
const identity = await verifyLinkedinLearningIdentity(page);
} catch (e) {
if (e.message.includes('whoami failed')) {
await page.reload(); // transient in-page failure
return verifyLinkedinLearningIdentity(page);
}
throw e;
} Prevention
- Read the embedded detail to distinguish TypeError (shape change) from network errors.
- Use optional chaining in the probe when reading Voyager response fields.
- Reload the page and retry before assuming a code bug.
- Pin/track LinkedIn API changes — response shape drift is the top cause.
When it happens
Trigger: page.evaluate callback throws — e.g. fetch to /voyager/api/me rejects (network/TLS error in page), reading response JSON throws, or firstName/lastName fields are absent causing a TypeError.
Common situations: LinkedIn changed the /voyager/api/me response shape (renamed fields), so `.included[0]` access throws; navigation interrupted the fetch; LinkedIn served an unexpected HTML interstitial that broke JSON parsing.
Related errors
- HTTP ${result.httpStatus} from /voyager/api/me
- LinkedIn Learning searchV2 failed: ${result?.error ?? 'no pa
- LinkedIn Learning searchV2 returned malformed payload: missi
- LinkedIn Learning feedRecommendationGroups failed: ${result?
- LinkedIn Learning feedRecommendationGroups returned malforme
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/c5d63cec33836671.
Report an issue: GitHub.