{"record":{"id":"37317cf153b04c29","repo":"facebook/relay","slug":"commitmutation-expected-mutation-operation","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/applyOptimisticMutation.js","lineNumber":54,"sourceCode":"  optimisticResponse?: Object,\n};\n\n/**\n * Higher-level helper function to execute a mutation against a specific\n * environment.\n */\nfunction applyOptimisticMutation<TMutation extends MutationParameters>(\n  environment: IEnvironment,\n  config: OptimisticMutationConfig<TMutation>,\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  let {optimisticUpdater} = config;\n  const {configs, optimisticResponse, variables} = config;\n  const operation = createOperationDescriptor(mutation, variables);\n  if (configs) {\n    ({optimisticUpdater} = RelayDeclarativeMutationConfig.convert(\n      configs,\n      mutation,\n      optimisticUpdater,\n    ));\n  }\n\n  return environment.applyMutation({\n    operation,\n    response: optimisticResponse,\n    updater: optimisticUpdater,\n  });\n}","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/packages/relay-runtime/mutations/applyOptimisticMutation.js#L36-L72","documentation":"applyOptimisticMutation's commitMutation validates that the compiled operation passed in config.mutation has operationKind === 'mutation'. This error means a non-mutation operation (query, subscription, or a plural/abstract operation) was supplied to an optimistic mutation commit.","triggerScenarios":"Calling commitMutation(environment, {mutation: SomeQuery}) where the GraphQL document was compiled as a query/subscription; or passing the wrong generated artifact ($Parameters import) to the optimistic mutation API.","commonSituations":"Importing the wrong generated file after editing the GraphQL document and changing its operation keyword; copying a query request into a mutation call; codegen mismatches where the .graphql file says 'query' but the JS treats it as a mutation.","solutions":["Ensure the .graphql file declares `mutation MutationName { ... }` and re-run relay-compiler to regenerate artifacts","Check that the imported module in config.mutation is the intended mutation's generated artifact, not a query's","If you intended a subscription, use requestSubscription; if a query, use fetchQuery/usePreloadedQuery instead"],"exampleFix":"// before (Mutation.graphql)\nquery UpsertUserMutation($input: X!) { ... }\n// after\nmutation UpsertUserMutation($input: X!) { ... }","handlingStrategy":"validation","validationCode":"import assert from 'assert';\nimport {getRequest} from 'relay-runtime';\nconst mutation = getRequest(config.mutation);\nassert.strictEqual(mutation.params.operationKind, 'mutation', 'config.mutation must be a compiled mutation');","typeGuard":"function isMutationRequest(req: {params: {operationKind: string}}): boolean {\n  return req.params.operationKind === 'mutation';\n}","tryCatchPattern":"try {\n  commitMutation(environment, config);\n} catch (e) {\n  if (e.message.includes('Expected mutation operation')) {\n    console.error('Wrong artifact passed to commitMutation:', config.mutation.params.name);\n  }\n}","preventionTips":["Type mutation configs with the generated $Parameters types so wrong artifacts fail at compile time","Name mutation GraphQL operations with a Mutation suffix and match import names","Recompile after editing operation keywords","Add a unit test asserting operationKind for every mutation config used in the app"],"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"}