{"record":{"id":"4f6619c78fd7f48e","repo":"santifer/career-ops","slug":"vdab-all-keywords-length-keyword-request-s-fa","errorCode":null,"errorMessage":"vdab: all ${keywords.length} keyword request(s) failed — ${errors[0]}","messagePattern":"vdab: all (.+?) keyword request\\(s\\) failed — (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/vdab.mjs","lineNumber":311,"sourceCode":"          try {\n            const detail = await keyedFetchJson(`${DETAIL_API}${encodeURIComponent(job.id)}?preview=false`, {\n              method: 'GET',\n              headers: { accept: 'application/json' },\n            });\n            const description = extractDescription(detail);\n            if (description) job.description = description;\n          } catch {\n            // Detail fetch is an enrichment only. Keep the listing result.\n          }\n        }));\n      }\n    }\n\n    // Total outage = every keyword 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(`vdab: all ${keywords.length} keyword request(s) failed — ${errors[0]}`);\n    }\n\n    return [...byId.values()].map(({ id, ...job }) => job);\n  },\n};\n","sourceCodeStart":293,"sourceCodeEnd":317,"githubUrl":"https://github.com/santifer/career-ops/blob/9b17a8ac97b398a496b38e423ae24e433b43254f/providers/vdab.mjs#L293-L317","documentation":"VDAB is queried with one POST per keyword; the provider is recall-first and tolerates individual keyword failures (it pushes them onto an errors[] array and keeps going). This throws only on a total outage — when succeeded (keywords whose request completed, regardless of how many results came back) is 0 and at least one error was recorded. The message surfaces only the first error to keep logs readable.","triggerScenarios":"Every per-keyword POST to https://www.vdab.be/rest/vindeenjob/v4/vacatureLight/zoek failed: VDAB rotated VEJ_KEY_MONITOR AND deriveKeyFromBundle() could not find the new key in the live bundle; a network/DNS failure to vdab.be; a 5xx; the WAF blocking the scanner's IP on all requests; or every request timing out.","commonSituations":"VDAB pushed a frontend redeploy and changed the key-extraction markup so KEY_RE/BUNDLE_RE no longer match; the scanner IP got rate-limited or geo-blocked; a transient VDAB outage during a scan; VDAB changed the API path.","solutions":["Retry the scan a few minutes later — most causes (5xx, transient WAF, network) clear on their own.","Inspect the first reported error: a 403 means key rotation — verify deriveKeyFromBundle still matches VDAB's bundle and update KEY_RE/BUNDLE_RE if the markup changed.","Open https://www.vdab.be/vindeenjob/vacatures in a browser to confirm the site and API are up from your network.","If IP-blocked, route the scan through a different egress or reduce concurrency.","As a last resort, patch VEJ_KEY_MONITOR with the current key copied from VDAB's frontend bundle."],"exampleFix":"// diagnostically re-run one keyword to see the real upstream error:\nconst ctx = makeCtx();\ntry {\n  await ctx.fetchJson(\n    \"https://www.vdab.be/rest/vindeenjob/v4/vacatureLight/zoek\",\n    { method: \"POST\", headers: { \"content-type\": \"application/json\" },\n      body: JSON.stringify({ /* buildSearchBody payload */ }) }\n  );\n} catch (e) { console.error(\"vdab upstream error:\", e.status, e.message); }","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"let jobs = [];\ntry {\n  jobs = await vdabProvider.fetch(entry, ctx);\n} catch (err) {\n  if (/vdab: all \\d+ keyword request\\(s\\) failed/.test(err.message)) {\n    // total outage — record and continue with other providers, do not abort the scan\n    results.push({ provider: \"vdab\", error: err.message, skipped: true });\n    continue;\n  }\n  throw err;\n}","preventionTips":["Treat this as a per-provider skip, not a fatal scan error — wrap each provider's fetch in its own try/catch.","Log the full first error, not just the summary, so key-rotation vs network vs 5xx is distinguishable.","On repeated 403s, proactively refresh VEJ_KEY_MONITOR from VDAB's bundle before the self-heal path degrades."],"tags":["network","vdab","outage","retry","key-rotation"],"backgroundTag":null,"analyzedSha":"9b17a8ac97b398a496b38e423ae24e433b43254f","analyzedAt":"2026-08-13T00:48:39.135Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}