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

  1. Remove the `categories` key entirely to fall back to the 'programming' default
  2. Add at least one valid category slug to the list
  3. 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

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


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