santifer/career-ops · error · Error
torre: unexpected API response — expected { results: [...] }
Error message
torre: unexpected API response — expected { results: [...] }, got keys: [${json ? Object.keys(json).join(', ') : 'null'}] What it means
After posting the search body to the Torre API, fetch() validates the JSON response has a 'results' array. Anything else — null body, an error object, a wrapped envelope — throws this error listing the keys actually received. This check fails the whole fetch (Torre does a single search request, unlike Muse's tolerant pagination).
Source
Thrown at providers/torre.mjs:218
assertTorreUrl(SEARCH_ENDPOINT);
const body = JSON.stringify(buildTorreQuery(entry));
const fallbackCompany = entry?.name;
// Exactly one request: the endpoint caps at 20 rows and ignores every
// pagination form, so a loop could only refetch the same page (quirk 2).
// ctx.maxPages needs no handling for the same reason — one page is all
// there is, which is already what the health probe wants.
const url = `${SEARCH_ENDPOINT}?offset=0&size=${PAGE_SIZE}`;
// redirect:'error' prevents SSRF via server-side redirects
const json = await ctx.fetchJson(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body,
redirect: 'error',
});
if (!json || !Array.isArray(json.results)) {
throw new Error(
`torre: unexpected API response — expected { results: [...] }, got keys: [${json ? Object.keys(json).join(', ') : 'null'}]`,
);
}
const out = [];
const seen = new Set();
for (const o of json.results) {
const normalized = normalizeTorreOpportunity(o, fallbackCompany);
if (!normalized || seen.has(normalized.url)) continue;
seen.add(normalized.url);
out.push(normalized);
}
return out;
},
};
View on GitHub (pinned to 1696bec4d0)
Solutions
- Read the keys printed in the message — they identify what came back (e.g. {error, message} points to an auth/quota problem).
- Retry after a delay; transient 429/5xx responses often arrive as malformed bodies.
- Verify API credentials, endpoint URL, and required headers for the Torre provider are current.
- Check for proxy/WAF interference on your network if the body is an HTML/challenge payload.
- If the envelope changed upstream, update the response parsing in providers/torre.mjs fetch() to the new schema.
Defensive patterns
Strategy: type-guard
Type guard
function isTorreSearchResponse(json) {
return !!json && typeof json === 'object' && !Array.isArray(json) &&
Array.isArray(json.results);
} Try / catch
try {
const jobs = await torreProvider.fetch(entry, ctx);
} catch (err) {
if (String(err.message).startsWith('torre: unexpected API response')) {
console.warn('Torre search returned an unexpected body:', err.message);
// inspect keys in message; back off and retry, or check credentials
} else throw err;
} Prevention
- Keep Torre API credentials and endpoint config current — error bodies usually mean auth/quota issues.
- Watch for provider updates after any known Torre API version change.
- Run a smoke search before batch scans to catch envelope changes early.
- Investigate proxy/WAF interference if response bodies look like challenge pages.
When it happens
Trigger: The Torre search POST returns a non-standard body: an auth/quota error object, an empty 204/empty-body response, a WAF/Cloudflare challenge page parsed as JSON, or an upstream schema change moving results into a nested field.
Common situations: Torre API outage or rate limiting; invalid/missing API credentials surfacing as an error-shaped JSON body; corporate proxy replacing responses; Torre changing its search response envelope after an API version bump.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- themuse: unexpected API response on page 0 — expected { resu
- HTTP ${res.status}${snippet ? ': ' + snippet.replace(/\s+/g,
- vc-portfolios: YC API fetch failed — ${err.message}
- [models] Failed to fetch free model list: ${reason}. Check t
- HTTP ${resp.status}: ${t.slice(0, 120)}
AI-assisted analysis of santifer/career-ops@1696bec4d0 (2026-09-01).
Data as JSON: /api/errors/dcc07ffb5a768110.
Report an issue: GitHub.