santifer/career-ops · error
arbeitsagentur: all keyword request(s) failed
Error message
arbeitsagentur: all ${keywords.length} keyword request(s) failed — ${errors[0]} What it means
After running one request per keyword, the provider distinguishes 'zero results' (legitimate) from 'zero successful requests' (outage). If every keyword request failed and at least one error was recorded, it throws summarizing the count and the first error — a total outage of the Bundesagentur für Arbeit search endpoint, not an empty labor market.
Solutions
- Read errors[0] in the message to classify: network/DNS => check connectivity/proxy; 4xx parameter => re-check parseArbeitsagenturConfig outputs against the current API; 429/5xx => retry with backoff later.
- Test one keyword manually with curl replicating the was/wo/umkreis params to see the raw failure.
- If the endpoint was redesigned, update fetchKeyword's parameter building and response parsing in providers/arbeitsagentur.mjs.
- Retry the scan after a backoff window — transient outages throw this on the whole entry but recover on a later run.
Example fix
// caller-side: retry the whole entry once on total outage before surfacing
try {
jobs = await arbeitsagentur.fetch(entry, ctx);
} catch (err) {
if (/all \d+ keyword request\(s\) failed/.test(err.message) && isTransient(err)) {
await sleep(60_000);
jobs = await arbeitsagentur.fetch(entry, ctx);
} else throw err;
} Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: one cheap request to see if the endpoint answers at all
const probe = await fetch('https://rest.arbeitsagentur.de/jobboerse/jobsuche-service/pc/v4/jobs?was=test&angebotsart=4', { headers: { accept: 'application/json' } });
if (!probe.ok) throw new Error(`arbeitsagentur endpoint unhealthy pre-scan: HTTP ${probe.status}`); Type guard
function isTotalOutage(err) {
return /all \d+ keyword request\(s\) failed/.test(String(err?.message));
} Try / catch
try {
jobs = await provider.fetch(entry, ctx);
} catch (err) {
if (isTotalOutage(err) && attempt < 2) {
await new Promise(r => setTimeout(r, 60_000 * (attempt + 1)));
return fetchEntryWithRetry(entry, ctx, attempt + 1);
}
throw err;
} Prevention
- Schedule scans outside known maintenance windows and accept that arbeitsagentur outages recover on retry.
- Read errors[0] in the message first: transient (5xx/timeout) vs systemic (4xx parameter/auth) needs different fixes.
- Check corporate proxy/firewall reachability to the arbeitsagentur hosts before blaming the API.
- Keep per-keyword successes count (not result count) as the outage signal — empty results are legitimate.
When it happens
Trigger: All primary keyword requests to the arbeitsagentur APIs failed — endpoint down or redesigned, network/TLS blocked from the host, every request rate-limited or session-token rejected, or a systemic parameter error (e.g. invalid umkreis/size) that fails identically for each keyword.
Common situations: The arbeitsagentur API has an outage or maintenance window; corporate proxy/firewall blocks the host; the API started rejecting the provider's parameter combination after an update; sustained 429s during a large sweep where every keyword hit the throttle.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- mycareersfuture: all
- vdab: all keyword request(s) failed
- 4dayweek: unexpected API response on page
- a16z-speedrun-talent: unexpected API response on page
- agentic-jobs: unexpected API response shape on page
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/a5486b8dc7bbb357.
Report an issue: GitHub.
Appendix: source
Thrown at providers/arbeitsagentur.mjs:260
wide
.map(normalizeJob)
.filter(Boolean)
.filter(job => !byRef.has(job.refnr))
.map(job => [job.refnr, job]),
).values()];
for (const job of wideJobs) {
if (remoteMatch !== 'filter' || REMOTE_RE.test(job.title)) {
job.location = job.location ? `${job.location} · Deutschlandweit (Homeoffice)` : 'Deutschlandweit (Homeoffice)';
}
if (!byRef.has(job.refnr)) byRef.set(job.refnr, job);
}
}
// Total outage = every primary request failed. A keyword that answered with
// zero results is not an outage, so key off the success count, not the
// deduped result size — otherwise a legitimately-empty search throws.
if (succeeded === 0 && errors.length) {
throw new Error(`arbeitsagentur: all ${keywords.length} keyword request(s) failed — ${errors[0]}`);
}
return [...byRef.values()].map(({ refnr, ...job }) => job);
},
};
View on GitHub (pinned to aac998c7ed)