santifer/career-ops · error · Error
hackernews: could not find "Ask HN: Who is hiring?" thread i
Error message
hackernews: could not find "Ask HN: Who is hiring?" thread in search results
What it means
Thrown by hackernews fetch() when resolveLatestThreadId(searchData) returns null after querying the Algolia HN search API (filtered to tags=story,author_whoishiring). It means the search returned no usable monthly 'Ask HN: Who is hiring?' thread id. The provider searches by the whoishiring account tag precisely so a free-text query cannot surface an unrelated story; a null result therefore points at a data/availability problem, not a ranking problem.
Source
Thrown at providers/hackernews.mjs:153
const RE = /ask\s+hn[:\s]+who\s+is\s+hiring/i;
for (const hit of hits) {
if (hit && typeof hit.objectID === 'string' && typeof hit.title === 'string') {
if (RE.test(hit.title)) return hit.objectID;
}
}
return null;
}
/** @type {Provider} */
export default {
id: 'hackernews',
async fetch(entry, ctx) {
// Step 1: Find the latest "Who is hiring?" story id.
const searchData = await ctx.fetchJson(SEARCH_URL, { redirect: 'error' });
const threadId = resolveLatestThreadId(searchData);
if (!threadId) {
throw new Error('hackernews: could not find "Ask HN: Who is hiring?" thread in search results');
}
const threadHnUrl = `https://news.ycombinator.com/item?id=${threadId}`;
// Step 2: Fetch the thread item (children = top-level job comments).
const item = await ctx.fetchJson(itemUrl(threadId), { redirect: 'error' });
if (!item || typeof item !== 'object') {
throw new Error(`hackernews: unexpected item response for thread ${threadId}`);
}
const children = /** @type {any} */ (item).children;
if (!Array.isArray(children)) return [];
// Step 3: Parse each comment.
const jobs = [];
for (const child of children) {
// Skip deleted / dead / empty comments.
if (!child || child.deleted || child.dead) continue;View on GitHub (pinned to 9b17a8ac97)
Solutions
- Retry on the next scan run (the thread typically appears within the first few days of the month).
- Verify the search endpoint directly: open https://hn.algolia.com/api/v1/search_by_date?tags=story,author_whoishiring&hitsPerPage=5 in a browser and confirm hits[] is populated.
- If Algolia is persistently down, temporarily disable the hackernews board entry (enabled: false) until it recovers.
- Check that ctx.fetchJson is not silently returning a cached/empty body from a proxy.
Defensive patterns
Strategy: retry
Validate before calling
// Probe the Algolia search endpoint before driving the provider.
const probe = await ctx.fetchJson(SEARCH_URL, { redirect: 'error' });
if (!Array.isArray(probe?.hits) || probe.hits.length === 0) {
console.warn('hackernews: search index unavailable this run — skipping');
continue;
} Type guard
/** Algolia search response carrying at least one whoishiring story. */
function hasHiringHits(json) {
return !!json && typeof json === 'object'
&& Array.isArray(json.hits) && json.hits.length > 0
&& json.hits.some(h => h && typeof h.objectID === 'string');
} Try / catch
for (let attempt = 0; attempt < 2; attempt++) {
try {
return await hackernewsProvider.fetch(entry, ctx);
} catch (err) {
const transient = /could not find .* thread in search results/.test(err.message);
if (!transient || attempt === 1) throw err;
await new Promise(r => setTimeout(r, 5000)); // back off, then retry once
}
} Prevention
- Expect this to fire in the first days of a month before the new thread is live — treat as transient, not a bug.
- Verify the Algolia search URL in a browser when the error persists to distinguish outage from data lag.
- Do not widen resolveLatestThreadId's acceptance criteria — that reintroduces the free-text false-positive problem the author filter was added to fix.
When it happens
Trigger: Algolia's HN index is lagging or temporarily unavailable (5xx/empty hits); it is the very start of a month before the whoishiring account has posted the new thread; a network/timeout error returned a 200 with a degenerate body; the Algolia tags query changed behaviour. Since the lookup is filtered to the whoishiring author, a null hit means that author's thread genuinely is not in the returned hits.
Common situations: Running a scan in the first days of a new month before the thread is live; transient Algolia outage or rate limiting; a corporate proxy returning an HTML interstitial parsed as JSON; DNS/connectivity failure to hn.algolia.com.
Related errors
- hackernews: unexpected item response for thread ${threadId}
- DNS resolution returned no addresses for ${hostname}
- Access denied: Egress guard blocked private target IP ${ip}
- [models] Failed to fetch free model list: ${reason}. Check t
- Pinned model timed out after ${MODEL_TIMEOUT_MS / 1000}s
AI-assisted analysis of santifer/career-ops@9b17a8ac97 (2026-08-13).
Data as JSON: /api/errors/35ab688c10e199bb.
Report an issue: GitHub.