jackwener/OpenCLI · critical · AuthRequiredError

${label} authentication failed (HTTP ${result.status || 'aut

Error message

${label} authentication failed (HTTP ${result.status || 'auth_required'}).

What it means

This AuthRequiredError is thrown by fetchSalesnavJson when the in-page fetch reports authRequired — Sales Navigator returned an authentication failure (HTTP 401/403 or a redirect to login) instead of thread JSON, even though a CSRF token was found.

Source

Thrown at clis/linkedin/salesnav-inbox.js:127

      if (res.status === 401 || res.status === 403) return { authRequired: true, status: res.status, text };
      if (!res.ok) return { error: 'HTTP ' + res.status, status: res.status, text, json };
      return { status: res.status, json };
    } catch (e) {
      return { error: 'fetch failed: ' + ((e && e.message) || String(e)) };
    }
  })()`;
}

export async function getCsrf(page) {
  const cookies = await page.getCookies({ url: 'https://www.linkedin.com' });
  const jsession = cookies.find((c) => c.name === 'JSESSIONID')?.value;
  if (!jsession) throw new AuthRequiredError(LINKEDIN_DOMAIN, 'LinkedIn JSESSIONID cookie not found. Please sign in to LinkedIn.');
  return jsession.replace(/^\"|\"$/g, '');
}

export async function fetchSalesnavJson(page, csrf, url, label) {
  const result = unwrapEvaluateResult(await page.evaluate(fetchJsonScript(url, csrf)));
  if (result?.authRequired) throw new AuthRequiredError(LINKEDIN_DOMAIN, `${label} authentication failed (HTTP ${result.status || 'auth_required'}).`);
  if (result?.error || !result?.json) throw new CommandExecutionError(`${label} returned an unexpected response`, `${result?.error || 'no_json'}\n${normalizeWhitespace(result?.text || '').slice(0, 500)}`);
  return result.json;
}

export async function fetchInboxRows(page, { limit = DEFAULT_LIMIT, maxPages = 30 } = {}) {
  const csrf = await getCsrf(page);
  const rows = [];
  const seen = new Set();
  let pageStartsAt = '';
  let pagesFetched = 0;
  let hasMorePages = false;
  while (rows.length < limit && pagesFetched < maxPages) {
    const json = await fetchSalesnavJson(page, csrf, threadListUrl({ count: PAGE_SIZE, pageStartsAt }), 'Sales Navigator messaging threads API');
    pagesFetched += 1;
    const pageRows = parseSalesnavThreads(json);
    if (pageRows.length === 0) break;
    for (const row of pageRows) {
      if (seen.has(row.thread_id)) continue;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-authenticate / sign in again and restart the scrape with a fresh session
  2. Shorten run duration and persist/refresh cookies so long jobs re-validate the session
  3. Verify the account has active Sales Navigator access to the messaging API
  4. Back off and retry later if LinkedIn is throttling the account

Example fix

// before
await fetchInboxRows(page); // may fail mid-run on expiry
// after
try {
  await fetchInboxRows(page);
} catch (e) {
  if (e instanceof AuthRequiredError) { await relogin(page); await fetchInboxRows(page); }
  else throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

const csrf = await getCsrf(page);
if (!csrf) throw new Error('No CSRF token; sign in to LinkedIn Sales Navigator first');

Type guard

null

Try / catch

try {
  const rows = await fetchInboxRows(page);
} catch (e) {
  if (String(e.message).includes('authentication failed')) {
    await relogin(page); // refresh session + cookies
    return fetchInboxRows(page);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling fetchSalesnavJson (via fetchInboxRows/json/fetchThreadWithPagination) when the LinkedIn session became invalid between getting the CSRF cookie and the API call — the endpoint replies with 401/403 or an auth redirect detected by the fetch script.

Common situations: Session expired mid-run (long scrapes); LinkedIn invalidated the session server-side; Sales Navigator license/lacking entitlement for the messaging endpoint; rate limiting that presents as an auth challenge.

Understand the failure class

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/e15bb9789308f517. Report an issue: GitHub.