santifer/career-ops · error · Error
manfred: unexpected API response — expected a JSON array of…
Error message
manfred: unexpected API response — expected a JSON array of offers, got ${json === null ? 'null' : typeof json} What it means
The Manfred fetch() calls the feed API and expects the JSON body to be an array of offer objects. If the parsed response is not an array (an object, string, number, or null), fetch() throws this error describing what type actually arrived. It guards against the API contract changing or an error/proxy page being returned with 200.
Solutions
- Log the actual response body at the failing URL to see what shape came back.
- Check whether the Manfred feed API changed shape and update the provider to unwrap the array (e.g. json.offers).
- Re-verify the feed URL is the offers-feed endpoint and not an error/docs endpoint.
- If a bot-protection layer is intercepting, retry from a normal network or adjust request headers via the fetch context.
Example fix
// before
if (!Array.isArray(json)) throw new Error(...);
const out = [];
for (const offer of json) {...}
// after (if API now wraps the array)
const offers = Array.isArray(json) ? json : Array.isArray(json?.offers) ? json.offers : null;
if (!offers) throw new Error('manfred: unexpected API response shape'); Defensive patterns
Strategy: try-catch
Type guard
const isOfferArray = (v) => Array.isArray(v) && v.every((o) => o && typeof o === 'object');
Try / catch
try {
const jobs = await provider.fetch(entry, ctx);
} catch (err) {
if (String(err.message).startsWith('manfred: unexpected API response')) {
const body = await fetch(feedUrl).then((r) => r.text());
console.error('Feed returned non-array body:', body.slice(0, 300));
return [];
}
throw err;
} Prevention
- Log the raw response body on shape mismatch to detect API contract changes early.
- Pin an integration test that asserts the live feed parses as an array.
- Handle wrapped envelope shapes ({offers:[...]}) defensively in downstream code.
- Treat a persistent shape error as an API-change signal, not a transient one — investigate the endpoint.
When it happens
Trigger: fetchJson resolves with valid JSON that is not an array: the API returned an error envelope like {"error":...}, a WAF/HTML-to-JSON gateway response, an empty object, or a literal null body.
Common situations: Manfred changes its feed response shape (wraps offers in {offers:[...]}); a captive portal or bot-protection layer intercepts the request and returns JSON that isn't the feed; the feed URL is valid but points at a non-feed endpoint.
Related errors
- collage: unrecognized response envelope (expected a…
- garena: unexpected API response — expected jobs[], got keys
- jobicy: unexpected API response — expected
- 4dayweek: unexpected API response on page
- a16z-speedrun-talent: unexpected API response on page
AI-assisted analysis of santifer/career-ops@e7abd431fc (2026-09-22).
Data as JSON: /api/errors/0687c18bf9826a18.
Report an issue: GitHub.
Appendix: source
Thrown at providers/manfred.mjs:210
/** @type {Provider} */
export default {
id: 'manfred',
detect(entry) {
return entry?.provider === 'manfred' ? { url: buildFeedUrl(entry) } : null;
},
async fetch(entry, ctx) {
// Validate the URL actually fetched (not just a constant) so the host pin
// is meaningful, then redirect:'error' blocks SSRF via server-side
// redirects — together they keep the request on getmanfred.com.
const url = assertManfredUrl(buildFeedUrl(entry));
const json = /** @type {any} */ (
await fetchJsonWithRetry(ctx, url, { redirect: 'error', timeoutMs: FETCH_TIMEOUT_MS })
);
if (!Array.isArray(json)) {
throw new Error(
`manfred: unexpected API response — expected a JSON array of offers, got ${json === null ? 'null' : typeof json}`,
);
}
const fallbackCompany = entry?.name;
const out = [];
for (const offer of json) {
const normalized = normalizeManfredOffer(offer, fallbackCompany);
if (normalized) out.push(normalized);
}
return out;
},
};
View on GitHub (pinned to e7abd431fc)