dgraph-io/dgraph · error

remote schema doesn't have any mutations.

Error message

remote schema doesn't have any mutations.

What it means

During validation of a @custom directive pointing at a remote GraphQL endpoint, the library introspects the remote schema. When the operation being validated is a mutation, the remote introspection result must contain a MutationType root; if the remote schema has no mutation root type, this error is returned. It means the remote endpoint simply cannot serve the mutation your custom directive references.

Source

Thrown at graphql/schema/remote.go:243

// validates the graphql given in @custom->http->graphql by introspecting remote schema.
// It assumes that the graphql syntax is correct, only remote validation is needed.
func validateRemoteGraphql(metadata *remoteGraphqlMetadata) error {
	remoteIntrospection, err := introspectRemoteSchema(metadata.url, metadata.headers)
	if err != nil {
		return err
	}

	var remoteQueryTypename string
	operationType := string(metadata.graphqlOpDef.Operation)
	switch operationType {
	case "query":
		if remoteIntrospection.Data.Schema.QueryType == nil {
			return errors.Errorf("remote schema doesn't have any queries.")
		}
		remoteQueryTypename = remoteIntrospection.Data.Schema.QueryType.Name
	case "mutation":
		if remoteIntrospection.Data.Schema.MutationType == nil {
			return errors.Errorf("remote schema doesn't have any mutations.")
		}
		remoteQueryTypename = remoteIntrospection.Data.Schema.MutationType.Name
	default:
		// this case is not possible as we are validating the operation to be query/mutation in
		// @custom directive validation
		return errors.Errorf("found `%s` operation, it can only have query/mutation.", operationType)
	}

	remoteTypes := make(map[string]*types)
	for _, typ := range remoteIntrospection.Data.Schema.Types {
		remoteTypes[typ.Name] = typ
	}

	remoteQryType, ok := remoteTypes[remoteQueryTypename]
	if !ok {
		return missingRemoteTypeError(remoteQueryTypename)
	}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Verify the remote endpoint URL in the @custom directive is the correct GraphQL endpoint and that its schema actually exposes a mutation root.
  2. Re-run the remote introspection to confirm MutationType is present; if the remote removed mutations, delete or convert the local mutation fields accordingly.
  3. Change the operation type of the custom directive to `query` if you only intended to read data.
  4. Check environment-specific config (staging vs prod) — some environments may disable mutations.

Example fix

// before
@custom(directive: {name: "custom", arguments: [{name: "http", value: {url: "https://api.example.com/graphql", method: POST}}], mode: SINGLE, operation: mutation})
// after
// point at an endpoint whose schema defines `type Mutation { ... }`, or switch to:
@custom(directive: {name: "custom", arguments: [{name: "http", value: {url: "https://api.example.com/graphql", method: GET}}], mode: SINGLE, operation: query})
Defensive patterns

Strategy: validation

Validate before calling

// before applying config, introspect the remote and check the root exists
const hasMutationRoot = introspection.__schema.mutationType != null
if (opType === 'mutation' && !hasMutationRoot) {
  throw new Error(`remote ${endpoint} has no mutation root; fix @custom directive config`)
}

Type guard

function hasMutationRoot(s) { return s?.__schema?.mutationType?.name != null }

Prevention

When it happens

Trigger: A field marked with @custom graphql(...) whose operation is `mutation` is validated, and remoteIntrospection.Data.Schema.MutationType is nil in the fetched remote introspection (graphql/schema/remote.go:243).

Common situations: Pointing a custom mutation at an introspection URL of a read-only schema (e.g. a gateway exposing only queries, a CDN-published SDL without mutation root, or the wrong endpoint/env URL); remote service updated to remove mutations while local config still declares them.

Related errors


AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01). Data as JSON: /api/errors/7b0603ef6a0074b6. Report an issue: GitHub.