Errors & Validation
Most APIs treat failure as a separate channel: a 404, a 500, a body you parse differently when things go wrong. GraphQL takes a different stance. A single response can describe both what succeeded and what failed, in one shape, at the same time. That shape is the heart of this module.
A GraphQL response is a JSON object with up to three top-level keys: data, errors, and extensions. The first holds whatever the server managed to resolve. The second is a list of everything that went wrong. They are not mutually exclusive — a response can carry a filled-out data tree and a non-empty errors array at once.
Errors are part of the contract
Section titled “Errors are part of the contract”We have called the schema a contract throughout this course. Errors are written into that contract too. The specification fixes the shape of an error object, the rules for where null may appear when a field fails, and the guarantee that a transport-level success (an HTTP 200) can still wrap a failed operation. Clients are expected to read errors, not just data.
This is liberating once you internalize it. You stop thinking “did the request succeed?” as a yes/no question and start thinking “which parts succeeded, which parts failed, and what does each failure tell the client to do?” A good GraphQL API answers all three in one round trip.
The shape of every response
Section titled “The shape of every response”flowchart TD Response["GraphQL response (JSON)"] Data["data — what resolved"] Errors["errors — list of failures"] Extensions["extensions — optional metadata"] Response --> Data Response --> Errors Response --> Extensions Errors -->|"path"| Data
The diagram shows the three branches. data mirrors the shape of the query. errors is a flat list, where each entry points back into data with a path. extensions is a free-form bag the server may use to attach machine-readable detail — we will spend a whole lesson on it.
What this module covers
Section titled “What this module covers”This module is about the failure side of the contract. The five lessons are:
- Errors & Validation (you are here) — the
data/errorsresponse shape and why errors are first-class. - GraphQL Errors — the
errorsarray in detail:message,locations,path, and request errors vs field errors. - Partial Results — how nullability controls error propagation, letting siblings resolve while one field fails.
- Error Extensions — typed errors with
extensions, throwingGraphQLError, and masking internals in production. - Input Validation — what the schema validates for free vs business rules you enforce in resolvers.
A response that carries an error
Section titled “A response that carries an error”Enough theory. The runner below defines a one-field schema whose resolver throws. Press Run and read the result: notice that data is present (it is null for the failed field) and errors describes what happened.
Read the output as one object. data.currentTrack came back null because its resolver threw and the field was nullable. Alongside it, errors holds a single entry describing the failure. Neither key cancels the other out — that coexistence is exactly what makes GraphQL error handling different from a plain HTTP status code.