santifer/career-ops · error · Error
wttj: unexpected Algolia response for query "${query}" — exp
Error message
wttj: unexpected Algolia response for query "${query}" — expected { hits: [...] }, got keys: [${json ? Object.keys(json).join(', ') : 'null'}] What it means
For each configured query the provider POSTs to ${appId}-dsn.algolia.net/1/indexes/wttj_jobs_production_en/query and expects a response object with a hits array. This throws when the response is null/falsy or hits is not an array — i.e. Algolia returned an error envelope instead of results.
Source
Thrown at providers/wttj.mjs:200
attributesToRetrieve:
'name,slug,organization,offices,remote,published_at_timestamp,salary_yearly_minimum,salary_maximum,salary_period,salary_currency',
});
const json = /** @type {any} */ (
await ctx.fetchJson(url, {
method: 'POST',
redirect: 'error',
headers: {
'x-algolia-application-id': appId,
'x-algolia-api-key': apiKey,
// The client search key is referer-locked to the WTTJ site.
referer: `${SITE_ORIGIN}/`,
'content-type': 'application/json',
},
body: JSON.stringify({ params: params.toString() }),
})
);
if (!json || !Array.isArray(json.hits)) {
throw new Error(
`wttj: unexpected Algolia response for query "${query}" — expected { hits: [...] }, got keys: [${json ? Object.keys(json).join(', ') : 'null'}]`,
);
}
for (const h of json.hits) {
const job = normalizeWttjHit(h);
if (job && !byUrl.has(job.url)) byUrl.set(job.url, job);
}
}
return [...byUrl.values()];
},
};
View on GitHub (pinned to 9b17a8ac97)
Solutions
- Inspect the reported keys in the message — { message, status } indicates an Algolia auth/error response; act on its status.
- Re-derive fresh credentials by re-fetching /api/env (parseEnvPayload) in case the key rotated.
- Verify the Referer header is being sent as https://www.welcometothejungle.com/ (the key is referer-locked).
- If the index was renamed, update the INDEX constant.
- Retry after a backoff if it is a rate limit.
Example fix
// before — treat any non-hits as fatal with raw keys
if (!json || !Array.isArray(json.hits)) {
throw new Error(`wttj: unexpected Algolia response for query "${query}" — got keys: [${json ? Object.keys(json).join(", ") : "null"}]`);
}
// after — surface Algolia's own error message for diagnosis
if (!json || !Array.isArray(json.hits)) {
const alg = json?.message ? ` (Algolia: ${json.message}, status ${json.status ?? "?"})` : "";
throw new Error(`wttj: unexpected Algolia response for query "${query}"${alg}`);
} Defensive patterns
Strategy: try-catch
Validate before calling
// probe credentials + index before the scan
const probe = await ctx.fetchJson(
`https://${appId}-dsn.algolia.net/1/indexes/${INDEX}/query`,
{ method: "POST",
headers: { "x-algolia-application-id": appId, "x-algolia-api-key": apiKey,
referer: SITE_ORIGIN + "/" },
body: JSON.stringify({ params: new URLSearchParams({ query: "test", hitsPerPage: "1" }).toString() }) }
);
if (!Array.isArray(probe?.hits)) console.warn("wttj algolia not returning hits — check key/index"); Type guard
const isAlgoliaHitsResponse = (j) => !!j && Array.isArray(j.hits);
Try / catch
try {
for (const query of queries) { /* Algolia POST */ }
} catch (err) {
if (/unexpected Algolia response/.test(err.message)) {
logAuthOrContractIssue("wttj", err.message);
continue;
}
throw err;
} Prevention
- Always send the WTTJ Referer header — the client key is referer-locked.
- Re-derive credentials each run (already done via /api/env) so a rotated key self-heals.
- Alert on this error to catch index renames or key-rotation failures early.
When it happens
Trigger: Algolia returned { message, status } (auth failure, invalid key, index missing); the referer-locked key was rejected because the Referer header was stripped; rate limit / quota exceeded; the index wttj_jobs_production_en was renamed; a network proxy returned a non-Algolia JSON body.
Common situations: The client search key expired or the referer lock no longer matches WTTJ's configured allowed referer; WTTJ renamed the production index; Algolia rate-limiting the scanner; a transient 4xx mapped to a JSON error body.
Related errors
- wttj: unexpected Algolia app id "${appId}"
- wttj: unexpected Algolia api key shape
- wttj: untrusted ${label} hostname "${parsed.hostname}" — mus
- wttj: /api/env payload has no JSON object
- wttj: /api/env payload is not valid JSON
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/74df7ae66299f8e4.
Report an issue: GitHub.