jackwener/OpenCLI · error · AuthRequiredError
LinkedIn Learning auth failed (HTTP ${result.status ?? ''}).
Error message
LinkedIn Learning auth failed (HTTP ${result.status ?? ''}). What it means
An AuthRequiredError thrown when the in-page API fetch returns HTTP 401 or 403 — buildFetchScript maps those statuses to {authRequired:true, status}. Unlike error 2275, a JSESSIONID cookie existed, but the server rejected the request: the session cookie is stale/expired or the derived csrf-token did not match, so LinkedIn's API rejected the authenticated call.
Source
Thrown at clis/linkedin-learning/shared.js:57
return { error: 'fetch failed: ' + ((e && e.message) || String(e)) };
}
})()`;
}
export async function fetchLinkedInLearningApi(page, url) {
await page.goto('https://www.linkedin.com/learning/');
await page.wait(3);
const cookies = await page.getCookies({ url: 'https://www.linkedin.com' });
const jsession = cookies.find((c) => c.name === 'JSESSIONID')?.value;
if (!jsession) {
throw new AuthRequiredError(DOMAIN, 'LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn in the browser.');
}
const csrf = jsession.replace(/^"|"$/g, '');
const result = unwrapEvaluateResult(await page.evaluate(buildFetchScript(url, csrf)));
if (result?.authRequired) {
throw new AuthRequiredError(DOMAIN, `LinkedIn Learning auth failed (HTTP ${result.status ?? ''}).`);
}
return result;
}
View on GitHub (pinned to 49907e53dc)
Solutions
- Re-login in the controlled browser to refresh the session, then retry.
- If 403 persists, check account standing/region access to LinkedIn Learning in the web UI.
- Confirm the csrf-token header equals JSESSIONID with surrounding double quotes stripped.
- Clear linkedin.com cookies and sign in fresh (stale-cookie mismatch).
- Retry after completing any LinkedIn verification prompt in the browser.
Example fix
// before const csrf = jsession.replace(/^"|"$/g, ''); // assumes only quote trimming is needed // after const csrf = decodeURIComponent(jsession.replace(/^"|"$/g, '')); if (result?.authRequired && result.status === 401) throw new AuthRequiredError(DOMAIN, 'Session expired; re-login required.');
Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: confirm the session is live by hitting a cheap authenticated page
await page.goto('https://www.linkedin.com/learning/');
const signedOut = await page.evaluate(() => !!document.querySelector('a[href*="/login"]'));
if (signedOut) throw new Error('LinkedIn session expired; re-login before running API commands'); Type guard
function isAuthRejection(r) { return !!r && typeof r === 'object' && r.authRequired === true && typeof r.status === 'number'; } Try / catch
try {
const rows = await search(page, { keywords });
} catch (e) {
if (/auth failed \(HTTP 40[13]\)/.test(e.message)) {
await relogin(page); // refresh JSESSIONID, re-derive csrf
return search(page, { keywords }); // retry once with fresh session
}
throw e;
} Prevention
- Re-login periodically; JSESSIONID expires server-side even if the cookie exists
- Strip surrounding quotes from JSESSIONID exactly as the CLI does when comparing csrf values
- On 401 always refresh the session before retrying — the old cookie will keep failing
- Investigate 403 for account/region restrictions on LinkedIn Learning
- Watch for LinkedIn security challenges that silently downgrade sessions
When it happens
Trigger: The JSESSIONID is present but expired server-side (soft logout), the csrf header derived from JSESSIONID (quotes stripped) does not match what LinkedIn expects, or the account is restricted/blocked from the learning-api endpoint (403).
Common situations: Long-lived automation profiles whose session silently expired, LinkedIn rotating session tokens after a security event, corporate/region restrictions returning 403, or clock/JAR inconsistencies after cookie export.
Related errors
- Gmail ${operation} returned HTTP ${status}
- 未登录或登录已过期,请先在浏览器中登录贝壳找房
- MiniMax ${region.host} rejected ${MINIMAX_API_KEY_VAR} (HTTP
- NotebookLM RPC returned auth error (${errorCode})
- This action requires being logged in to Pinterest in Chrome
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/5af44b21b46ba562.
Report an issue: GitHub.