{"record":{"id":"3adb95f32f2eee9a","repo":"facebook/relay","slug":"commitmutation-expected-mutation-operation-3adb95","errorCode":null,"errorMessage":"commitMutation: Expected mutation operation","messagePattern":"commitMutation: Expected mutation operation","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/relay-runtime/mutations/commitMutation.js","lineNumber":96,"sourceCode":" * Higher-level helper function to execute a mutation against a specific\n * environment.\n */\nfunction commitMutation<\n  TVariables extends Variables,\n  TData,\n  TRawResponse = {...},\n>(\n  environment: IEnvironment,\n  config: CommitMutationConfig<TVariables, TData, TRawResponse>,\n): Disposable {\n  invariant(\n    isRelayModernEnvironment(environment),\n    'commitMutation: expected `environment` to be an instance of ' +\n      '`RelayModernEnvironment`.',\n  );\n  const mutation = getRequest(config.mutation);\n  if (mutation.params.operationKind !== 'mutation') {\n    throw new Error('commitMutation: Expected mutation operation');\n  }\n  if (mutation.kind !== 'Request') {\n    throw new Error('commitMutation: Expected mutation to be of type request');\n  }\n  let {optimisticResponse, optimisticUpdater, updater} = config;\n  const {configs, cacheConfig, onError, onUnsubscribe, variables, uploadables} =\n    config;\n  const operation = createOperationDescriptor(\n    mutation,\n    variables,\n    cacheConfig,\n    generateUniqueClientID(),\n  );\n  // TODO: remove this check after we fix flow.\n  if (typeof optimisticResponse === 'function') {\n    /* $FlowFixMe[incompatible-use] error exposed when improving flow typing of\n     * commitMutation */\n    optimisticResponse = optimisticResponse();","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/packages/relay-runtime/mutations/commitMutation.js#L78-L114","documentation":"commitMutation in relay-runtime checks that the request object built from config.mutation has operationKind 'mutation'. Supplying a compiled query or subscription throws this error before any network work begins.","triggerScenarios":"commitMutation(environment, {mutation: <generated query or subscription artifact>}) — i.e. the GraphQL document's operation keyword is `query` or `subscription` rather than `mutation`.","commonSituations":"Wrong generated module imported (auto-import picked the query file with a similar name); the .graphql operation keyword was changed or mistyped; renaming operations so the mutation import now points at a query artifact.","solutions":["Verify the .graphql file passed to relay-compiler uses `mutation` as the operation keyword and recompile","Confirm the import in config.mutation matches the generated artifact of the mutation (check params.operationKind in the artifact)","Use requestSubscription or fetchQuery if the operation is genuinely not a mutation"],"exampleFix":"// before\nimport CandidateQuery from './__generated__/CandidateQuery.graphql';\ncommitMutation(env, {mutation: CandidateQuery, ...});\n// after\nimport CandidateMutation from './__generated__/CandidateMutation.graphql';\ncommitMutation(env, {mutation: CandidateMutation, ...});","handlingStrategy":"validation","validationCode":"import {getRequest} from 'relay-runtime';\nconst mutation = getRequest(config.mutation);\nif (mutation.params.operationKind !== 'mutation') {\n  throw new Error(`${mutation.params.name} is a ${mutation.params.operationKind}, not a mutation`);\n}","typeGuard":"function isCommitableMutation(m: {params: {operationKind: string}}): m is {params: {operationKind: 'mutation'}} {\n  return m.params.operationKind === 'mutation';\n}","tryCatchPattern":"try {\n  const id = commitMutation(environment, config);\n} catch (e) {\n  if (e.message.includes('Expected mutation operation')) {\n    // wrong operation kind — redirect to requestSubscription/fetchQuery as appropriate\n  }\n}","preventionTips":["Import generated artifacts from the mutation's own __generated__ file","Verify params.operationKind in code review when wiring mutations","Use TypeScript $Parameters so mismatched artifacts are compile errors","Keep operation names unique to avoid auto-import confusion"],"tags":["mutations","graphql-operation-kind","relay-compiler"],"backgroundTag":"wrong-operation-kind","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}