{"record":{"id":"3e020dab28d0e325","repo":"facebook/relay","slug":"commitmutation-expected-mutation-to-be-of-type-re","errorCode":null,"errorMessage":"commitMutation: Expected mutation to be of type request","messagePattern":"commitMutation: Expected mutation to be of type request","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/relay-runtime/mutations/commitMutation.js","lineNumber":99,"sourceCode":"function 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();\n    warning(\n      false,\n      'commitMutation: Expected `optimisticResponse` to be an object, ' +","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/facebook/relay/blob/668b1b85e06261aa3b58dabfc51f8b5524a70955/packages/relay-runtime/mutations/commitMutation.js#L81-L117","documentation":"After confirming the operation kind, commitMutation checks mutation.kind === 'Request'. The compiled artifact passed must be a concrete request (a normalized, executable operation). Passing an older or different artifact shape (e.g. a plain query artifact, a PreloadableQuery, or a mismatched runtime type) fails this check.","triggerScenarios":"Passing a non-Request compiled object to commitMutation — e.g. an artifact produced by incompatible relay-compiler versions, a fragment-only reference, or mixing react-relay's commitMutation types with relay-runtime internals across mismatched package versions.","commonSituations":"Version skew between relay-compiler (build time) and relay-runtime (runtime) so generated artifact shapes differ; duplicated relay-runtime copies in node_modules; hand-crafted mutation objects in tests.","solutions":["Recompile GraphQL artifacts with the relay-compiler version matching your relay-runtime and confirm artifact.params/kind fields","Deduplicate relay-runtime/react-relay versions (npm ls relay-runtime) and reinstall","Pass the generated .graphql request module directly from @generated, not a custom wrapper"],"exampleFix":"// before (package.json mismatch)\n\"relay-compiler\": \"15.0.0\", \"relay-runtime\": \"13.2.0\"\n// after\n\"relay-compiler\": \"15.0.0\", \"relay-runtime\": \"15.0.0\"","handlingStrategy":"validation","validationCode":"import {getRequest} from 'relay-runtime';\nconst mutation = getRequest(config.mutation);\nif (mutation.params.operationKind !== 'mutation' || mutation.kind !== 'Request') {\n  throw new Error('commitMutation requires a compiled Request artifact of kind mutation');\n}","typeGuard":"function isRequestArtifact(a: unknown): a is {kind: 'Request', params: {operationKind: string}} {\n  return typeof a === 'object' && a !== null && (a as any).kind === 'Request';\n}","tryCatchPattern":"try {\n  commitMutation(environment, config);\n} catch (e) {\n  if (e.message.includes('Expected mutation to be of type request')) {\n    console.error('Artifact kind mismatch — recompile with matching relay-compiler version');\n  }\n}","preventionTips":["Keep relay-compiler and relay-runtime on identical versions","Recompile artifacts after every relay version bump","Run npm ls relay-runtime to ensure a single copy","Never hand-roll fake request objects in production code"],"tags":["mutations","artifact-shape","version-mismatch","relay-compiler"],"backgroundTag":"relay-artifact-version-mismatch","analyzedSha":"668b1b85e06261aa3b58dabfc51f8b5524a70955","analyzedAt":"2026-09-02T19:57:20.783Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}