{"record":{"id":"fef876581c7ab69b","repo":"santifer/career-ops","slug":"wttj-the-wttj-board-is-global-configure-explici","errorCode":null,"errorMessage":"wttj: the WTTJ board is global — configure explicit searches via `wttj: { queries: [\"…\"] }`","messagePattern":"wttj: the WTTJ board is global — configure explicit searches via `wttj: (.+?)`","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"providers/wttj.mjs","lineNumber":144,"sourceCode":"      : 0;\n  if (min || max) {\n    job.salary = {\n      min: min || max,\n      max: max || min,\n      currency: typeof h.salary_currency === 'string' ? h.salary_currency.trim().toUpperCase() : '',\n    };\n  }\n  return job;\n}\n\n/** Resolve config: required queries list + optional per-query hit cap. */\nfunction resolveConfig(entry) {\n  const cfg = entry?.wttj && typeof entry.wttj === 'object' ? entry.wttj : {};\n  const queries = Array.isArray(cfg.queries)\n    ? cfg.queries.filter((q) => typeof q === 'string' && q.trim()).map((q) => q.trim())\n    : [];\n  if (queries.length === 0) {\n    throw new Error(\n      'wttj: the WTTJ board is global — configure explicit searches via `wttj: { queries: [\"…\"] }`',\n    );\n  }\n  const maxHits =\n    Number.isInteger(cfg.max_hits) && cfg.max_hits > 0 ? Math.min(cfg.max_hits, MAX_HITS_CAP) : DEFAULT_MAX_HITS;\n  return { queries, maxHits };\n}\n\n/** @type {Provider} */\nexport default {\n  id: 'wttj',\n\n  detect(entry) {\n    return entry?.provider === 'wttj' ? { url: SITE_ORIGIN } : null;\n  },\n\n  async fetch(entry, ctx) {\n    const { queries, maxHits } = resolveConfig(entry);","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/santifer/career-ops/blob/1696bec4d021768e7359f9aad6b329cba883da20/providers/wttj.mjs#L126-L162","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Add explicit queries to the entry, e.g. `wttj: { queries: [\"rust backend\", \"paris\"] }`.","Check YAML indentation so `queries` actually nests under `wttj`.","Remove queries entries that are empty strings or whitespace-only.","If you did not intend to use WTTJ, delete the wttj block from the entry."],"exampleFix":"# before\n- name: my-search\n  wttj: {}\n# after\n- name: my-search\n  wttj:\n    queries:\n      - \"senior backend\"\n      - \"remote europe\"","handlingStrategy":"validation","validationCode":"const queries = (entry?.wttj?.queries ?? [])\n  .filter((q) => typeof q === 'string' && q.trim());\nif (queries.length === 0) {\n  throw new Error(`portal entry \"${entry.name}\": wttj requires wttj.queries = [\"...\"]`);\n}","typeGuard":"function hasWttjQueries(entry) {\n  return Array.isArray(entry?.wttj?.queries)\n    && entry.wttj.queries.some((q) => typeof q === 'string' && q.trim());\n}","tryCatchPattern":"try {\n  await wttjProvider.run(entry);\n} catch (e) {\n  if (e.message.includes('configure explicit searches')) {\n    console.error(`Skipping ${entry.name}: add wttj.queries to your portals config`);\n    return;\n  }\n  throw e;\n}","preventionTips":["Add a config sanity check at startup that every wttj entry has non-empty queries.","Copy provider entry templates with placeholders that fail loudly, not silently-empty defaults.","Verify YAML nesting (queries under wttj) after editing portals.yml."],"tags":["configuration","wttj","missing-config","yaml"],"backgroundTag":"missing-required-config","analyzedSha":"1696bec4d021768e7359f9aad6b329cba883da20","analyzedAt":"2026-09-01T19:19:23.111Z","contentChangedAt":"2026-09-01T19:19:23.111Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}