santifer/career-ops · error · Error

wttj: the WTTJ board is global — configure explicit…

Error message

wttj: the WTTJ board is global — configure explicit searches via `wttj: { queries: ["…"] }`

What it means

Thrown by resolveConfig() when a portals entry enables the wttj provider without any non-empty strings under wttj.queries. WTTJ's board is a single global index, so unlike per-company ATS providers it cannot infer scope — the user must supply explicit search query strings, otherwise the provider would scan the entire worldwide board.

Solutions

  1. Add explicit queries to the entry, e.g. `wttj: { queries: ["rust backend", "paris"] }`.
  2. Check YAML indentation so `queries` actually nests under `wttj`.
  3. Remove queries entries that are empty strings or whitespace-only.
  4. If you did not intend to use WTTJ, delete the wttj block from the entry.

Example fix

# before
- name: my-search
  wttj: {}
# after
- name: my-search
  wttj:
    queries:
      - "senior backend"
      - "remote europe"
Defensive patterns

Strategy: validation

Validate before calling

const queries = (entry?.wttj?.queries ?? [])
  .filter((q) => typeof q === 'string' && q.trim());
if (queries.length === 0) {
  throw new Error(`portal entry "${entry.name}": wttj requires wttj.queries = ["..."]`);
}

Type guard

function hasWttjQueries(entry) {
  return Array.isArray(entry?.wttj?.queries)
    && entry.wttj.queries.some((q) => typeof q === 'string' && q.trim());
}

Try / catch

try {
  await wttjProvider.run(entry);
} catch (e) {
  if (e.message.includes('configure explicit searches')) {
    console.error(`Skipping ${entry.name}: add wttj.queries to your portals config`);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Adding a portals.yml entry with `wttj: {}`, `wttj:` set to a non-object (string/null), an empty `queries: []`, or queries containing only empty/whitespace strings — then running a scan that resolves that entry.

Common situations: Copy-pasting a provider entry template and forgetting to fill in queries, YAML indentation errors nesting queries in the wrong place, or an env-driven config where the queries array came through empty.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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

Appendix: source

Thrown at providers/wttj.mjs:144

      : 0;
  if (min || max) {
    job.salary = {
      min: min || max,
      max: max || min,
      currency: typeof h.salary_currency === 'string' ? h.salary_currency.trim().toUpperCase() : '',
    };
  }
  return job;
}

/** Resolve config: required queries list + optional per-query hit cap. */
function resolveConfig(entry) {
  const cfg = entry?.wttj && typeof entry.wttj === 'object' ? entry.wttj : {};
  const queries = Array.isArray(cfg.queries)
    ? cfg.queries.filter((q) => typeof q === 'string' && q.trim()).map((q) => q.trim())
    : [];
  if (queries.length === 0) {
    throw new Error(
      'wttj: the WTTJ board is global — configure explicit searches via `wttj: { queries: ["…"] }`',
    );
  }
  const maxHits =
    Number.isInteger(cfg.max_hits) && cfg.max_hits > 0 ? Math.min(cfg.max_hits, MAX_HITS_CAP) : DEFAULT_MAX_HITS;
  return { queries, maxHits };
}

/** @type {Provider} */
export default {
  id: 'wttj',

  detect(entry) {
    return entry?.provider === 'wttj' ? { url: SITE_ORIGIN } : null;
  },

  async fetch(entry, ctx) {
    const { queries, maxHits } = resolveConfig(entry);

View on GitHub (pinned to 1696bec4d0)