{"record":{"id":"60e9352d233a621c","repo":"facebook/relay","slug":"unexpected-null-response-from-fetchquery","errorCode":null,"errorMessage":"Unexpected null response from fetchQuery","messagePattern":"Unexpected null response from fetchQuery","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/react-relay/relay-hooks/rsc/serverFetchQuery.js","lineNumber":26,"sourceCode":" * @format\n * @oncall relay\n */\n\n'use strict';\n\nimport type {IEnvironment, Query, Variables} from 'relay-runtime';\n\nconst {fetchQuery} = require('relay-runtime');\n\nasync function serverFetchQuery<TVariables extends Variables, TData>(\n  environment: IEnvironment,\n  query: Query<TVariables, TData>,\n  variables: TVariables,\n): Promise<TData> {\n  const observable = fetchQuery(environment, query, variables);\n  const result = await observable.toPromise();\n  if (result == null) {\n    throw new Error('Unexpected null response from fetchQuery');\n  }\n  return result;\n}\n\nmodule.exports = serverFetchQuery;\n","sourceCodeStart":8,"sourceCodeEnd":32,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/packages/react-relay/relay-hooks/rsc/serverFetchQuery.js#L8-L32","documentation":"serverFetchQuery is an RSC (React Server Components) wrapper around Relay's fetchQuery. It awaits the observable's promise and throws if Relay resolves with null/undefined, which should never happen for a well-formed query — a null result indicates the environment or network layer returned an empty payload instead of data or an error.","triggerScenarios":"Calling serverFetchQuery(environment, query, variables) in a server environment when the network layer's fetch resolves with null/undefined (e.g. missing response body, custom network layer returning undefined, or environment misconfiguration) instead of a valid GraphQLResponse.","commonSituations":"RSC server-side rendering with a misconfigured network layer; a fetch function that returns response.json() of an empty body (204/empty 200); a network layer that swallows errors and resolves undefined; SSR data prefetch where the environment has no handler for the query.","solutions":["Inspect the network layer's fetch function and make sure it always resolves with a valid GraphQLResponse containing a 'data' or 'errors' field","Check that the fetch response body is being parsed (e.g. await response.json()) and that the server actually returns a body for this query","Verify the environment passed to serverFetchQuery is a fully configured RelayModernEnvironment, not an empty/placeholder environment","If the error is expected (e.g. legitimately nullable data), handle the null in the network layer or wrap the call and surface a domain-specific error"],"exampleFix":"// before\nconst network = Network.create(() => fetch(url));\n// after\nconst network = Network.create(async (params, vars) => {\n  const res = await fetch(url, {method: 'POST', body: JSON.stringify({query: params.text, variables: vars})});\n  if (!res.ok) throw new Error(`GraphQL request failed: ${res.status}`);\n  return res.json(); // must resolve with {data} or {errors}\n});","handlingStrategy":"try-catch","validationCode":"const network = environment.getNetwork(); // verify fetch always resolves {data} or {errors}\n// sanity check before use:\nfunction isValidResponse(r) { return r != null && ('data' in r || 'errors' in r); }","typeGuard":"function isGraphQLResponse(r: unknown): r is {data: unknown} { return typeof r === 'object' && r !== null && 'data' in r; }","tryCatchPattern":"try {\n  const data = await serverFetchQuery(environment, query, variables);\n} catch (e) {\n  if (e.message.includes('Unexpected null response')) {\n    // network layer returned null: log request id/params and surface a server error\n  }\n  throw e;\n}","preventionTips":["Always parse and validate the fetch response body in your network layer","Never let a network layer resolve undefined; throw on !res.ok","Test your RSC network layer with an integration test per query","Log the query name/variables when this error fires to identify the failing environment"],"tags":["rsc","server-rendering","network-layer","null-response"],"backgroundTag":"null-fetch-response","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}