ErrLookup › Background articles › TypeError: Wrong Value Type at the API Boundary

TypeError: Wrong Value Type at the API Boundary

TypeError is the built-in exception both Python and JavaScript use when a value is not the type an operation expects, and in these libraries it surfaces less as a language quirk than as a deliberate fail-fast guard. A factory refuses a non-object config, a hook loop rejects a bad return value, a validator catches a constraint placed on the wrong field type. Developers meet it the moment they hand an API a value that breaks its documented shape: at construction, during request handling, or while a schema is being built.

Distilled from 1,068 documented records across 54 repositories.

Background

TypeError originates in the language runtime (ECMAScript's TypeError, Python's built-in TypeError), but the records show libraries raising it deliberately as an API-contract signal. Rather than letting a wrong-typed argument flow into code that would later crash with a cryptic AttributeError or corrupt state silently, the library performs an explicit typeof or isinstance check at the boundary and throws TypeError naming the expected shape. Multer's options guard rejects anything that is not a non-null object so its constructor can safely dereference options.storage and options.limits; aiohttp's AppRunner asserts isinstance(app, Application) before every downstream step assumes a real Application; Django's SpatialReference dispatches on whether the input is a str, int, or SRS pointer; n8n's assertPlainObject rejects null, arrays, and primitives before a builder spreads an argument's keys. The shared intent is fail-fast with a descriptive message rather than a downstream surprise.

From the caller's side the throw is usually synchronous and local. It fires at the call site (multer(...), AppRunner(app), model_dump(exclude=...)) or during an early lifecycle step such as schema build, config finalization, or migration authoring. A subset fire during request handling: Koa's app.onerror re-throws when middleware throws or rejects with a non-Error value, got's hook loops check each hook's return value against a strict contract, and node-fetch's formData() refuses a response whose content-type is not multipart. In nearly every case the message identifies the offending value's type or the constraint that was violated, so the fix is almost always at the call site rather than inside library internals.

The family splits into several shapes that behave differently. Pure type guards (multer, aiohttp, mysql2's ssl check, Django's SRS dispatch, n8n's builder) reject a value of the wrong runtime type. Contract enforcers (the got hook family, koa's onerror) police the return value or thrown value of an extension point. Security allow-lists use TypeError to block injection vectors: knex's operator formatter permits only a fixed list of SQL operators, ESLint rejects rules whose declared languages do not include the file's language, and got refuses non-native FormData. Schema-build mismatches catch annotations that are statically incompatible: pydantic rejects string constraints on non-string fields and numeric constraints on string fields, and Sequelize throws when a validate key does not resolve to a function. A few records are misleading or unreachable: node-fetch reports 'Failed to fetch' for what is really a content-type mismatch, axios carries a duplicate guard that current control flow never reaches, and pydantic's exclude message renders the raw class object rather than its clean name.

Whether a given misuse is reported as TypeError versus a library-specific subclass is library-specific, and the records disagree on strictness. got forbids any body on GET and HEAD by default for RFC alignment while other HTTP clients are more permissive; multer explicitly excludes null even though typeof null === 'object'; got accepts boolean true for ssl but mysql2 throws on truthy non-object ssl values. Some guards are essentially defensive and never fire under normal control flow (axios), while others are load-bearing security controls (knex). Treat the message as a strong hint, but confirm the exact guard against the library's source when the behavior is surprising.

Common causes

What usually fixes it

Go deeper

Documented occurrences

…and 1,048 more across the corpus — use search.

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