facebook/relay · error

commitMutation: Expected mutation to be of type request

Error message

commitMutation: Expected mutation to be of type request

What it means

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.

Source

Thrown at packages/relay-runtime/mutations/commitMutation.js:99

function commitMutation<
  TVariables extends Variables,
  TData,
  TRawResponse = {...},
>(
  environment: IEnvironment,
  config: CommitMutationConfig<TVariables, TData, TRawResponse>,
): Disposable {
  invariant(
    isRelayModernEnvironment(environment),
    'commitMutation: expected `environment` to be an instance of ' +
      '`RelayModernEnvironment`.',
  );
  const mutation = getRequest(config.mutation);
  if (mutation.params.operationKind !== 'mutation') {
    throw new Error('commitMutation: Expected mutation operation');
  }
  if (mutation.kind !== 'Request') {
    throw new Error('commitMutation: Expected mutation to be of type request');
  }
  let {optimisticResponse, optimisticUpdater, updater} = config;
  const {configs, cacheConfig, onError, onUnsubscribe, variables, uploadables} =
    config;
  const operation = createOperationDescriptor(
    mutation,
    variables,
    cacheConfig,
    generateUniqueClientID(),
  );
  // TODO: remove this check after we fix flow.
  if (typeof optimisticResponse === 'function') {
    /* $FlowFixMe[incompatible-use] error exposed when improving flow typing of
     * commitMutation */
    optimisticResponse = optimisticResponse();
    warning(
      false,
      'commitMutation: Expected `optimisticResponse` to be an object, ' +

View on GitHub (pinned to 668b1b85e0)

Solutions

  1. Recompile GraphQL artifacts with the relay-compiler version matching your relay-runtime and confirm artifact.params/kind fields
  2. Deduplicate relay-runtime/react-relay versions (npm ls relay-runtime) and reinstall
  3. Pass the generated .graphql request module directly from @generated, not a custom wrapper

Example fix

// before (package.json mismatch)
"relay-compiler": "15.0.0", "relay-runtime": "13.2.0"
// after
"relay-compiler": "15.0.0", "relay-runtime": "15.0.0"
Defensive patterns

Strategy: validation

Validate before calling

import {getRequest} from 'relay-runtime';
const mutation = getRequest(config.mutation);
if (mutation.params.operationKind !== 'mutation' || mutation.kind !== 'Request') {
  throw new Error('commitMutation requires a compiled Request artifact of kind mutation');
}

Type guard

function isRequestArtifact(a: unknown): a is {kind: 'Request', params: {operationKind: string}} {
  return typeof a === 'object' && a !== null && (a as any).kind === 'Request';
}

Try / catch

try {
  commitMutation(environment, config);
} catch (e) {
  if (e.message.includes('Expected mutation to be of type request')) {
    console.error('Artifact kind mismatch — recompile with matching relay-compiler version');
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of facebook/relay@668b1b85e0 (2026-09-02). Data as JSON: /api/errors/3e020dab28d0e325. Report an issue: GitHub.