santifer/career-ops · error · Error

jobbankca: all ${keywords.length} keyword request(s) failed

Error message

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

What it means

fetch() fans out one request per keyword and tolerates individual failures, but if every keyword's first request failed (succeeded === 0) it declares a total outage and throws, surfacing the first underlying error. A keyword returning zero results is NOT an outage — only network/HTTP failures count.

Source

Thrown at providers/jobbankca.mjs:298

          }
          break;
        }

        const rawEntryCount = (String(xml ?? '').match(/<entry\b[^>]*>[\s\S]*?<\/entry>/gi) || []).length;
        const parsed = parseJobBankFeed(xml);
        for (const job of parsed) {
          if (!byUrl.has(job.url)) byUrl.set(job.url, job);
        }
        if (rawEntryCount < PAGE_SIZE) break; // short feed page — end of this keyword's results
      }
      if (!keywordFailed) succeeded++;
    }

    // Total outage = every keyword's first request failed. A keyword that
    // answered with zero results is not an outage — recall-first, same as
    // arbeitsagentur.mjs.
    if (succeeded === 0 && errors.length) {
      throw new Error(`jobbankca: all ${keywords.length} keyword request(s) failed — ${errors[0]}`);
    }

    return [...byUrl.values()];
  },
};

View on GitHub (pinned to 1696bec4d0)

Solutions

  1. Read errors[0] in the message — it contains the actual root cause (ECONNREFUSED, 403, 429, etc.) and fix that first
  2. Retry later with backoff if it's a 429/5xx transient outage
  3. Verify network/DNS/proxy access: curl -v https://jobbank.canada.ca/... from the same machine
  4. Reduce request rate / add delays between keyword requests if rate-limited

Example fix

// before: no retry
await jobbankca.fetch(entry, ctx);
// after
try {
  await jobbankca.fetch(entry, ctx);
} catch (e) {
  if (/429|timeout|ECONN/i.test(e.message)) {
    await new Promise(r => setTimeout(r, 30_000));
    await jobbankca.fetch(entry, ctx);
  } else throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

// Preflight reachability check before a full scan
const probe = await fetch('https://jobbank.canada.ca', { method: 'HEAD' }).catch(() => null);
if (!probe || !probe.ok) console.warn('jobbank.ca unreachable — scan may fail');

Try / catch

try {
  const jobs = await jobbankca.fetch(entry, ctx);
} catch (e) {
  const m = e.message.match(/all (\d+) keyword request\(s\) failed — (.*)/);
  if (m) {
    console.error(`jobbankca outage, root cause: ${m[2]}`);
    if (/429|5\d\d|timeout|ECONN|ENOTFOUND/i.test(m[2])) scheduleRetry(60_000);
  } else throw e;
}

Prevention

When it happens

Trigger: All keyword requests to the Job Bank endpoint fail: network down, DNS failure, TLS error, 429 rate-limit on the first page of each keyword, 5xx from the service, or a proxy blocking outbound HTTPS.

Common situations: Corporate proxy/firewall blocking jobbank.canada.ca, transient Job Bank outage or maintenance window, aggressive scanning triggering rate limits, running in an offline CI container.

Related errors


AI-assisted analysis of santifer/career-ops@1696bec4d0 (2026-09-01). Data as JSON: /api/errors/c8e0d6cc3c1b3edf. Report an issue: GitHub.