santifer/career-ops · error · Error
deutschebahn: cannot resolve db.jobs search id for ${entry.n
Error message
deutschebahn: cannot resolve db.jobs search id for ${entry.name} What it means
Thrown by the deutschebahn provider's fetch() when resolveConfig(entry) returns null. resolveConfig needs an http(s) URL whose host is exactly db.jobs or ends in .db.jobs. (It falls back to a well-known search id when the path lacks one, so a missing search id is NOT the cause — the failure is host/URL resolution, despite the message mentioning the search id.)
Source
Thrown at providers/deutschebahn.mjs:112
function resolveMaxPages(entry) {
const v = entry?.max_pages;
if (Number.isInteger(v) && v > 0) return Math.min(v, MAX_PAGES);
return MAX_PAGES;
}
/** @type {Provider} */
export default {
id: 'deutschebahn',
detect(entry) {
const url = entry.api || entry.careers_url || '';
if (typeof url !== 'string') return null;
return resolveConfig({ api: url }) ? { url } : null;
},
async fetch(entry, ctx) {
const cfg = resolveConfig(entry);
if (!cfg) throw new Error(`deutschebahn: cannot resolve db.jobs search id for ${entry.name}`);
const wait = (ms) => (ctx.sleep ? ctx.sleep(ms) : new Promise((r) => setTimeout(r, ms)));
const maxPages = resolveMaxPages(entry);
const jobs = [];
const seen = new Set();
for (let page = 0; page < maxPages; page++) {
if (page > 0) await wait(PAGE_DELAY_MS);
const url = `${cfg.searchBase}?qli=true&query=&sort=score&itemsPerPage=${ITEMS_PER_PAGE}&pageNum=${page}`;
const html = await ctx.fetchText(url, { headers: { accept: 'text/html' } });
const rows = parseHits(html, cfg.origin);
if (rows.length === 0) break; // past the last page
let fresh = 0;
for (const row of rows) {
if (seen.has(row.id)) continue;
seen.add(row.id);
fresh++;View on GitHub (pinned to 9b17a8ac97)
Solutions
- Set api: (or careers_url:) to the canonical db.jobs search URL, e.g. https://db.jobs/service/search/de-de/5441588.
- If you only have the branded URL, follow its redirect once to capture the underlying db.jobs URL and configure that.
- Gate with provider.detect(entry) (returns null when resolveConfig does) before fetch().
Example fix
# before — branded host, not db.jobs - name: Deutsche Bahn provider: deutschebahn careers_url: https://jobs.deutschebahngroup.careers # after — canonical db.jobs URL - name: Deutsche Bahn provider: deutschebahn api: https://db.jobs/service/search/de-de/5441588
Defensive patterns
Strategy: validation
Validate before calling
import deutschebahn from './providers/deutschebahn.mjs';
if (!deutschebahn.detect(entry)) {
// entry.api/entry.careers_url is not http(s)://(*.)db.jobs/... — set it to the db.jobs URL
} Type guard
/** True when entry resolves to a db.jobs host (the failure is host resolution, not the search id). */
function isDeutscheBahnEntry(entry) {
const raw = typeof entry?.api === 'string' ? entry.api : (typeof entry?.careers_url === 'string' ? entry.careers_url : '');
if (!raw) return false;
let u;
try { u = new URL(raw); } catch { return false; }
if (u.protocol !== 'https:' && u.protocol !== 'http:') return false;
const host = u.host.toLowerCase();
return host === 'db.jobs' || host.endsWith('.db.jobs');
} Try / catch
try { await deutschebahn.fetch(entry, ctx); }
catch (e) {
if (/^deutschebahn: cannot resolve db.jobs search id/.test(e.message)) {
// host/URL resolution failed — set api: to https://db.jobs/service/search/de-de/5441588; do not retry
} else throw e;
} Prevention
- Use the canonical db.jobs URL, not the branded jobs.deutschebahngroup.careers redirect.
- The search id defaults to a known value, so the fix is the host, not the id.
- Run detect() before fetch().
When it happens
Trigger: entry.api/entry.careers_url is missing, unparseable, uses a non-http(s) protocol, or its host is not db.jobs / *.db.jobs. The branded jobs.deutschebahngroup.careers host redirects into db.jobs but is itself on a different domain, so pointing at the branded host directly can fail detection.
Common situations: Configuring the branded jobs.deutschebahngroup.careers URL (which 302-redirects into db.jobs) instead of the canonical db.jobs URL; an http-vs-https mix-up; omitting the URL entirely.
Related errors
- breezy: cannot derive API URL for ${entry.name}
- comeet: cannot derive API URL for ${entry.name} (set api: to
- consider: ${entry.name} needs an https careers_url on a publ
- csod: cannot resolve careersite URL for ${entry.name}
- eightfold: cannot derive API URL for ${entry.name}
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/7561a8ca1efb0bfc.
Report an issue: GitHub.