jackwener/OpenCLI · error · CommandExecutionError

${label} returned an unexpected response

Error message

${label} returned an unexpected response

What it means

This CommandExecutionError is thrown by fetchSalesnavJson when the API response neither required auth nor yielded JSON — i.e. result.error is set or result.json is missing. The detail includes the error key plus up to 500 chars of the raw text so the caller can see what actually came back.

Source

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

      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;
      seen.add(row.thread_id);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the error detail (result.error and first 500 chars of text) to identify the actual response
  2. Retry the request — transient 5xx/network issues often resolve on retry with backoff
  3. Verify the endpoint URL is current (Sales Nav API paths change) and the CSRF token was sent correctly
  4. Check whether an HTML challenge/redirect page is being served and re-authenticate if so

Example fix

// before
const json = await fetchSalesnavJson(page, csrf, url, 'inbox');
// after
let json;
try { json = await fetchSalesnavJson(page, csrf, url, 'inbox'); }
catch (e) { await sleep(2000); json = await fetchSalesnavJson(page, csrf, url, 'inbox'); }
Defensive patterns

Strategy: retry

Validate before calling

const probe = await fetchSalesnavJson(page, csrf, healthUrl, 'healthcheck');
if (!probe) throw new Error('Sales Nav endpoint not returning JSON; check session/endpoint');

Type guard

function isJsonResult(r) {
  return !!r && typeof r === 'object' && !r.error && 'json' in r && r.json != null;
}

Try / catch

try {
  const json = await fetchSalesnavJson(page, csrf, url, 'inbox');
} catch (e) {
  if (String(e.message).includes('unexpected response')) {
    await sleep(2000 * attempt); // backoff, log detail from e
    return fetchSalesnavJson(page, csrf, url, 'inbox');
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling fetchSalesnavJson when the Sales Nav endpoint returns non-JSON (HTML error page, empty body, 5xx text), an in-page fetch exception (network failure, CSP block), or a JSON envelope the script flags as error.

Common situations: LinkedIn serving an HTML error/challenge page; server-side 5xx during the request; wrong endpoint URL producing 404 HTML; browser context blocking the fetch (extensions/CSP); transient network failure inside page.evaluate.

Related errors


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