ErrLookupBackground articles › "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong

"invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong

"invalid response format", "malformed payload", and "missing data field" errors all belong to one family: the HTTP request succeeded, the body parsed as JSON, but the payload does not have the structure the library expects — a missing field, a non-array where an array was expected, or an error envelope served with a 200 status. Developers hit these errors when an upstream API changes its schema, a proxy or CDN substitutes its own response, an auth session silently expired, or an error body masquerades as a success payload.

Distilled from 106 documented records across 23 repositories.

Background

This family sits at a specific layer: after the network call succeeds and after JSON parsing succeeds, but before the library hands data to your code. The HTTP status was 2xx, resp.json() or JSON.parse didn't throw, and yet the decoded value is missing a key, has a field of the wrong type, or has the wrong top-level shape (an array or string where an object was expected, null where a list was expected). Libraries raise these errors deliberately as contract guards: rather than silently returning an empty result or crashing later on a TypeError deep inside mapping code, they validate the envelope once and fail with a descriptive message. Record [1] states the intent plainly — the throw exists so callers can assume payload.field access is safe.

Why do 200 responses carry wrong-shaped bodies at all? The records converge on a handful of mechanisms. Upstream APIs serve error envelopes with success statuses: GitHub device-flow errors delivered with 200 [13], DashScope throttled responses with non-standard bodies [24], Alpha Vantage signaling errors through JSON keys rather than HTTP statuses [18], GraphQL returning a top-level errors array alongside null data [6][21]. Auth layers degrade quietly: an expired Pixiv or BOSS session or a logged-out Manus profile yields an error envelope or login page instead of the real payload [2][14][23]. Intermediaries interfere: proxies, CDNs, WAFs, and SSL-inspecting middleboxes substitute HTML error pages, cached JSON, or re-encoded bodies [3][7][12][24]. And finally, the API itself changes — fields get renamed, envelopes get restructured, query IDs go stale.

From the caller's side these errors look uniform but mean different things. Some libraries embed a truncated raw payload in the message to make diagnosis instant — OpenCLI's Douyin error includes the first 500 characters of the response [10], career-ops embeds 200 characters of the run-creation body [12], and the Mastra Kimi error names the operation that failed [29]. Others leave you to log the body yourself. The strictness also varies: some checks demand exact types (a string token and numeric expires_at in Copilot token validation [16], an integer 0/1 from a Lua restore script [17]), while others accept any of several known keys (OpenCLI's Manus skills check accepts userAddedSkills, systemSkills, or skills [8]) or deliberately distinguish an empty-but-valid payload ([] for an empty Apify dataset [5]) from a structurally wrong one.

A recurring distinction across the family is between contract drift and caller mistakes. Several records explicitly note that reaching the shape check means earlier error paths were already handled — Sourcegraph's GraphQL errors array is consumed before the missing-data check fires [6], Alpha Vantage's Note/Information/ErrorMessage keys are handled before the missing bestMatches case [18], and ONES' business-error fields are checked before the missing-groups case [11]. So when this error fires, it usually means something outside the documented error vocabulary happened: schema drift, a proxy in the path, or an auth state the library didn't anticipate.

Common causes

What usually fixes it

Go deeper

Documented occurrences

…and 86 more across the corpus — use search.

Honest provenance: generated on 2026-08-30 from AI-assisted analysis of the linked records. See how records are made.