{"record":{"id":"a5486b8dc7bbb357","repo":"santifer/career-ops","slug":"arbeitsagentur-all-keywords-length-keyword-req","errorCode":null,"errorMessage":"arbeitsagentur: all ${keywords.length} keyword request(s) failed — ${errors[0]}","messagePattern":"arbeitsagentur: all (.+?) keyword request\\(s\\) failed — (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/arbeitsagentur.mjs","lineNumber":253,"sourceCode":"        wide\n          .map(normalizeJob)\n          .filter(Boolean)\n          .filter(job => !byRef.has(job.refnr))\n          .map(job => [job.refnr, job]),\n      ).values()];\n      for (const job of wideJobs) {\n        if (remoteMatch !== 'filter' || REMOTE_RE.test(job.title)) {\n          job.location = job.location ? `${job.location} · Deutschlandweit (Homeoffice)` : 'Deutschlandweit (Homeoffice)';\n        }\n        if (!byRef.has(job.refnr)) byRef.set(job.refnr, job);\n      }\n    }\n\n    // Total outage = every primary request failed. A keyword that answered with\n    // zero results is not an outage, so key off the success count, not the\n    // deduped result size — otherwise a legitimately-empty search throws.\n    if (succeeded === 0 && errors.length) {\n      throw new Error(`arbeitsagentur: all ${keywords.length} keyword request(s) failed — ${errors[0]}`);\n    }\n\n    return [...byRef.values()].map(({ refnr, ...job }) => job);\n  },\n};\n","sourceCodeStart":235,"sourceCodeEnd":259,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/providers/arbeitsagentur.mjs#L235-L259","documentation":"Arbeitsagentur runs one request per keyword and tolerates individual failures (some keywords can legitimately return zero). This error fires only on a *total outage*: `succeeded === 0` (no keyword request succeeded) while `errors.length > 0`. The message surfaces the first error so the root cause is visible. A legitimately-empty search does not trigger this — emptiness is keyed off success count, not result size.","triggerScenarios":"Every primary keyword request threw an error and none succeeded. `errors[0]` is attached to the thrown message. Triggered by network failure, DNS issues, the Arbeitsagentur Jobsuche API being down, or all requests being blocked (e.g. by rate-limiting / IP ban).","commonSituations":"Total network outage, the Jobsuche API endpoint changed or is under maintenance, the scanner's IP got rate-limited/blocked across all keywords, or a misconfigured proxy breaks every outbound request.","solutions":["Read the appended first error (`errors[0]`) — it is the actual failure (network, status, parse) repeated across keywords.","Check connectivity to the Arbeitsagentur API host and verify the endpoint URL is still valid.","If rate-limited, reduce concurrency/keyword count and retry after a cooldown.","Confirm a single keyword works in isolation to rule out a config issue vs. an outage."],"exampleFix":"// before — any partial failure aborts everything\nif (errors.length) throw new Error(`arbeitsagentur: failed — ${errors[0]}`);\n\n// after — only a total outage throws, surfacing the first error\nif (succeeded === 0 && errors.length) {\n  throw new Error(`arbeitsagentur: all ${keywords.length} keyword request(s) failed — ${errors[0]}`);\n}","handlingStrategy":"retry","validationCode":"// Pre-flight connectivity check to the Arbeitsagentur API before fanning out keywords\ntry {\n  await ctx.fetchJson(buildProbeUrl(), { timeoutMs: 5000 });\n} catch (e) {\n  throw new Error(`arbeitsagentur: API unreachable in pre-flight (${e.message}) — aborting before keyword fan-out`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  // per-keyword requests collecting into `errors`/`succeeded`\n} catch (err) {\n  errors.push(err); // individual failures are tolerated\n}\nif (succeeded === 0 && errors.length) {\n  // total outage — retry once with backoff, then surface errors[0]\n  throw new Error(`arbeitsagentur: all ${keywords.length} keyword request(s) failed — ${errors[0]}`);\n}","preventionTips":["Do a single cheap pre-flight request before fanning out all keywords so an outage fails fast.","Apply backoff+jitter across keywords to avoid triggering rate-limits that block every request.","Log per-keyword errors so the root cause is visible even when only the first is surfaced."],"tags":["arbeitsagentur","network","outage","retry-logic"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}