{"record":{"id":"e123618a652c82f0","repo":"facebook/relay","slug":"fetchquery-expected-query-operation","errorCode":null,"errorMessage":"fetchQuery: Expected query operation","messagePattern":"fetchQuery: Expected query operation","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/relay-runtime/query/fetchQuery_DEPRECATED.js","lineNumber":37,"sourceCode":"  createOperationDescriptor,\n} = require('../store/RelayModernOperationDescriptor');\nconst {getRequest} = require('./GraphQLTag');\n\n/**\n * A helper function to fetch the results of a query. Note that results for\n * fragment spreads are masked: fields must be explicitly listed in the query in\n * order to be accessible in the result object.\n */\n\nfunction fetchQuery_DEPRECATED<T extends OperationType>(\n  environment: IEnvironment,\n  taggedNode: GraphQLTaggedNode,\n  variables: T['variables'],\n  cacheConfig?: ?CacheConfig,\n): Promise<T['response']> {\n  const query = getRequest(taggedNode);\n  if (query.params.operationKind !== 'query') {\n    throw new Error('fetchQuery: Expected query operation');\n  }\n  const operation = createOperationDescriptor(query, variables, cacheConfig);\n  return environment\n    .execute({operation})\n    .map(() => environment.lookup(operation.fragment).data)\n    .toPromise();\n}\n\nmodule.exports = fetchQuery_DEPRECATED;\n","sourceCodeStart":19,"sourceCodeEnd":47,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/packages/relay-runtime/query/fetchQuery_DEPRECATED.js#L19-L47","documentation":"fetchQuery_DEPRECATED only supports GraphQL queries: it executes an operation and resolves with its data. The throw guards against passing a mutation/subscription fragment, whose execution semantics differ, so Relay rejects it up front.","triggerScenarios":"Passing a graphql-tagged node whose params.operationKind is 'mutation' or 'subscription' to the deprecated fetchQuery(environment, taggedNode, variables) helper.","commonSituations":"Using a shared fragment/mutation constant by mistake in a preloading helper; refactoring code where the tag changed kind; forgetting that commitMutation/requestSubscription are the right entry points for non-query operations.","solutions":["Pass a query operation (use graphql`query ... {...}`) to fetchQuery","Use commitMutation (relay-experimental/commitMutation or environment) for mutations instead of fetchQuery","Use requestSubscription for subscriptions","Migrate off fetchQuery_DEPRECATED to fetchQuery, which produces a clearer pathway"],"exampleFix":"// before\nfetchQuery_DEPRECATED(env, graphql`mutation M { ... }`, vars);\n// after\ncommitMutation(env, {mutation: graphql`mutation M { ... }`, variables: vars});","handlingStrategy":"validation","validationCode":"const req = getRequest(taggedNode);\nif (req.params.operationKind !== 'query') {\n  throw new TypeError('fetchQuery requires a query operation, got ' + req.params.operationKind);\n}","typeGuard":"const isQueryOp = (tag) => getRequest(tag).params.operationKind === 'query';","tryCatchPattern":"try {\n  return await fetchQuery_DEPRECATED(env, tag, vars);\n} catch (e) {\n  if (e.message === 'fetchQuery: Expected query operation') {\n    throw new Error('Pass queries to fetchQuery; use commitMutation/requestSubscription for other kinds');\n  }\n  throw e;\n}","preventionTips":["Keep queries and mutations in separate modules/exports","Use relay-compiler typed graphql so operation kinds are typed","Prefer modern fetchQuery/commitMutation APIs","Name tagged constants by kind (e.g. xxxQuery, xxxMutation)"],"tags":["relay","graphql","wrong-operation-kind","deprecated-api"],"backgroundTag":"wrong-operation-kind","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}