santifer/career-ops · error · Error
getonbrd: `categories` is empty — omit it to use the "progra
Error message
getonbrd: `categories` is empty — omit it to use the "programming" default
What it means
After slug validation and deduplication, resolveCategories rejects an empty resulting list. An empty `categories` array would produce zero API requests, so the provider requires you to either omit the key (using DEFAULT_CATEGORY 'programming') or supply at least one valid slug.
Source
Thrown at providers/getonbrd.mjs:65
* @returns {string[]}
*/
export function resolveCategories(entry) {
const raw = entry?.categories !== undefined ? entry.categories : entry?.category;
if (raw === undefined || raw === null) return [DEFAULT_CATEGORY];
const list = Array.isArray(raw) ? raw : [raw];
const out = [];
for (const c of list) {
if (typeof c !== 'string' || !CATEGORY_SLUG_RE.test(c.trim())) {
throw new Error(
`getonbrd: invalid category ${JSON.stringify(c)} — expected a slug like "programming" or "machine-learning-ai"`,
);
}
const slug = c.trim();
if (!out.includes(slug)) out.push(slug);
}
if (!out.length) {
throw new Error('getonbrd: `categories` is empty — omit it to use the "programming" default');
}
if (out.length > MAX_CATEGORIES) {
throw new Error(
`getonbrd: ${out.length} categories configured — cap is ${MAX_CATEGORIES} (each one costs up to max_pages requests)`,
);
}
return out;
}
/** @param {string} url */
function assertGetonbrdUrl(url) {
let parsed;
try {
parsed = new URL(url);
} catch {
throw new Error(`getonbrd: invalid URL: ${url}`);
}
if (parsed.protocol !== 'https:') throw new Error(`getonbrd: URL must use HTTPS: ${url}`);View on GitHub (pinned to 1696bec4d0)
Solutions
- Remove the `categories` key entirely to fall back to the 'programming' default
- Add at least one valid category slug to the list
- Fix upstream templating/filtering that empties the array
Example fix
// before categories: [] // after # omit the key, or: categories: ['programming']
Defensive patterns
Strategy: validation
Validate before calling
const cats = Array.isArray(cfg.categories) ? cfg.categories : undefined;
if (cats && cats.length === 0) {
console.warn('categories is empty; omitting key to use default "programming"');
delete cfg.categories;
} Type guard
function hasNonEmptyCategories(entry) {
return !Array.isArray(entry.categories) || entry.categories.length > 0;
} Try / catch
try {
const jobs = await getonbrdProvider.fetch(entry, ctx);
} catch (e) {
if (String(e.message).includes('`categories` is empty')) {
console.warn('Empty categories list for', entry.name, '— falling back to default category');
return getonbrdProvider.fetch({ ...entry, categories: undefined }, ctx);
}
throw e;
} Prevention
- To mean 'all/default', omit the key instead of passing []
- Guard template rendering so unset categories are omitted, not emitted as empty lists
- Assert config invariants at load time
When it happens
Trigger: Configuring `categories: []` in the portal entry, or a config-merge/filter step that strips all entries before resolveCategories runs.
Common situations: Users assuming an empty array means 'all categories'; templating that renders an empty YAML list when no categories are set; programmatic filtering that removes everything.
Related errors
- gmail: invalid days_back "${ctx?.settings?.days_back}" (must
- ratePerMin must be a finite number > 0, got ${ratePerMin}
- capacity must be a finite number >= 1, got ${capacity}
- arbeitsagentur: entry "${entry.name || '(unnamed)'}" has no
- ashby: invalid URL: ${url}
AI-assisted analysis of santifer/career-ops@1696bec4d0 (2026-09-01).
Data as JSON: /api/errors/43451d60ab2fad21.
Report an issue: GitHub.