santifer/career-ops · error · Error

vdab: all ${keywords.length} keyword request(s) failed — ${e

Error message

vdab: all ${keywords.length} keyword request(s) failed — ${errors[0]}

What it means

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.

Source

Thrown at providers/vdab.mjs:311

          try {
            const detail = await keyedFetchJson(`${DETAIL_API}${encodeURIComponent(job.id)}?preview=false`, {
              method: 'GET',
              headers: { accept: 'application/json' },
            });
            const description = extractDescription(detail);
            if (description) job.description = description;
          } catch {
            // Detail fetch is an enrichment only. Keep the listing result.
          }
        }));
      }
    }

    // Total outage = every keyword 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(`vdab: all ${keywords.length} keyword request(s) failed — ${errors[0]}`);
    }

    return [...byId.values()].map(({ id, ...job }) => job);
  },
};

View on GitHub (pinned to 9b17a8ac97)

Solutions

  1. Retry the scan a few minutes later — most causes (5xx, transient WAF, network) clear on their own.
  2. 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.
  3. Open https://www.vdab.be/vindeenjob/vacatures in a browser to confirm the site and API are up from your network.
  4. If IP-blocked, route the scan through a different egress or reduce concurrency.
  5. As a last resort, patch VEJ_KEY_MONITOR with the current key copied from VDAB's frontend bundle.

Example fix

// diagnostically re-run one keyword to see the real upstream error:
const ctx = makeCtx();
try {
  await ctx.fetchJson(
    "https://www.vdab.be/rest/vindeenjob/v4/vacatureLight/zoek",
    { method: "POST", headers: { "content-type": "application/json" },
      body: JSON.stringify({ /* buildSearchBody payload */ }) }
  );
} catch (e) { console.error("vdab upstream error:", e.status, e.message); }
Defensive patterns

Strategy: retry

Try / catch

let jobs = [];
try {
  jobs = await vdabProvider.fetch(entry, ctx);
} catch (err) {
  if (/vdab: all \d+ keyword request\(s\) failed/.test(err.message)) {
    // total outage — record and continue with other providers, do not abort the scan
    results.push({ provider: "vdab", error: err.message, skipped: true });
    continue;
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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