santifer/career-ops · error · Error

themuse: unexpected API response on page ${page} — expected

Error message

themuse: unexpected API response on page ${page} — expected { results: [...] }, got keys: [${json ? Object.keys(json).join(', ') : 'null'}]

What it means

On each page fetch asserts the JSON has an Array 'results'. If json is null or json.results is not an array it throws and reports the actual top-level keys. The Muse API contract is { results: [...], page_count, ... }; a different shape on any page aborts the whole fetch (there is no partial-success fallback here, unlike thehub).

Source

Thrown at providers/themuse.mjs:74

      : '';
  return { title, url, company, location };
}

/** @type {Provider} */
export default {
  id: 'themuse',

  async fetch(_entry, ctx) {
    assertMuseUrl(FEED_BASE);
    const allResults = [];
    // Fetch page 0 first to discover page_count, then iterate remaining pages.
    let pageCount = 1;
    for (let page = 0; page < pageCount; page++) {
      const url = `${FEED_BASE}?page=${page}`;
      // redirect:'error' prevents SSRF via server-side redirects
      const json = await ctx.fetchJson(url, { redirect: 'error' });
      if (!json || !Array.isArray(json.results)) {
        throw new Error(
          `themuse: unexpected API response on page ${page} — expected { results: [...] }, got keys: [${json ? Object.keys(json).join(', ') : 'null'}]`,
        );
      }
      if (page === 0 && Number.isInteger(json.page_count) && json.page_count > 1) {
        pageCount = Math.min(json.page_count, 100);
      }
      allResults.push(...json.results);
    }
    return allResults.map(normalizeMuseJob).filter(Boolean);
  },
};

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Open https://www.themuse.com/api/public/jobs?page=0 in a browser and compare keys to the error
  2. Retry later if the API is down or rate-limiting
  3. If the contract changed, update the results-array check and normalizeMuseJob mapping in providers/themuse.mjs
Defensive patterns

Strategy: try-catch

Type guard

/** @param {unknown} json @returns {json is { results: any[] }} */
function isMuseResponse(json) {
  return !!json && typeof json === 'object' && Array.isArray(json.results);
}

Try / catch

try {
  const jobs = await provider.fetch(entry, ctx);
} catch (err) {
  if (/themuse: unexpected API response/.test(err.message)) {
    console.warn('The Muse API shape changed or is down — skipping');
    return [];
  }
  throw err;
}

Prevention

When it happens

Trigger: The Muse API returned an error body, an HTML/JSON hybrid, a rate-limit page, or a redesigned envelope. Because page_count drives iteration, a malformed page 0 also prevents further paging.

Common situations: API outage, version bump that renamed 'results', rate-limiting/CAPTCHA, or the public endpoint being deprecated/moved.

Related errors


AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13). Data as JSON: /api/errors/f37bfb8448fded49. Report an issue: GitHub.