santifer/career-ops · error · Error

agentic-jobs: parsed 0 jobs from the API — the response…

Error message

agentic-jobs: parsed 0 jobs from the API — the response shape likely changed

What it means

After the paging loop, the provider requires at least one parsed job; zero jobs from a board-wide feed means the response shape no longer matches the parser (records are fetched but none normalize), not that the board is empty. It throws so scan results don't silently report an empty provider as healthy.

Solutions

  1. Fetch a page manually (curl 'https://agentic-engineering-jobs.com/api/v1/jobs?page=1') and diff the record fields against what normalizeAgenticJob/the parser expects; update field mappings.
  2. Check the OpenAPI spec for a schema/version change and bump the provider to the current response contract.
  3. Add a debug log of the first raw record when jobs.length===0 to see exactly what shape arrives.
  4. Confirm meta.total: if total>0 but zero records normalize, it's a parser mismatch; if the board genuinely emptied, treat it as upstream data loss, not a code bug.

Example fix

// before
if (jobs.length === 0) throw new Error('agentic-jobs: parsed 0 jobs...');
// after (diagnosable)
if (jobs.length === 0) {
  throw new Error(`agentic-jobs: parsed 0 jobs — sample record: ${JSON.stringify(records?.[0])?.slice(0, 300)}`);
}
Defensive patterns

Strategy: validation

Validate before calling

const json = await fetch('https://agentic-engineering-jobs.com/api/v1/jobs?page=1').then(r => r.json());
if (Array.isArray(json.data) && json.data.length === 0 && json.meta?.total > 0) {
  throw new Error('API reports total>0 but returned 0 records — parser/shape mismatch, do not run scan');
}

Type guard

function looksParseable(record) {
  return !!record && typeof record === 'object' &&
    typeof record.title === 'string' && typeof record.slug === 'string';
}

Try / catch

try {
  jobs = await provider.fetch(entry, ctx);
} catch (err) {
  if (String(err.message).includes('parsed 0 jobs')) {
    console.error('Board feed parsed empty — verify upstream schema via the OpenAPI spec before assuming the board is empty');
  }
  throw err;
}

Prevention

When it happens

Trigger: The API returned pages successfully but every record failed normalization (field renames like companyName -> company_name, changed slug/title structure), or json.data was consistently an empty array while meta.total claimed >0 — i.e. every parsed record was dropped before reaching `jobs`.

Common situations: Upstream API renamed the fields the normalizer reads; a filter/normalizer regression after a provider edit; the API started wrapping records in an extra nesting level ({ data: { items: [...] } }) while per-page length checks still passed; site pivoted to a new API version at /api/v2 leaving v1 serving stub payloads.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16). Data as JSON: /api/errors/b0ff341f32145217. Report an issue: GitHub.

Appendix: source

Thrown at providers/agentic-jobs.mjs:193

      // Trust the API's own reported page size over our constant, in case it
      // ever differs from the documented default.
      const effectivePageSize = typeof json.meta?.per_page === 'number' && json.meta.per_page > 0 ? json.meta.per_page : PAGE_SIZE;

      for (const record of records) {
        const job = normalizeAgenticJob(record);
        if (job && !seen.has(job.url)) {
          seen.add(job.url);
          jobs.push(job);
        }
      }

      if (jobs.length >= MAX_JOBS) break;
      if (records.length < effectivePageSize) break; // short page — last one
      if (total !== null && page * effectivePageSize >= total) break;
    }

    if (jobs.length === 0) {
      throw new Error('agentic-jobs: parsed 0 jobs from the API — the response shape likely changed');
    }
    return jobs.slice(0, MAX_JOBS);
  },
};

View on GitHub (pinned to aac998c7ed)