dgraph-io/dgraph · error

remote schema doesn't have any queries.

Error message

remote schema doesn't have any queries.

What it means

During custom directive validation, Dgraph introspects the remote schema and reads its operation types. If the remote schema advertises no query type (Schema.QueryType is nil) while the local @custom usage needs a query, this error is raised. A GraphQL schema without queries is legal per spec but cannot serve the custom query fields Dgraph is validating.

Source

Thrown at graphql/schema/remote.go:238

	typMap map[string]*gqlType
	// requiredArgs is the list of NON_NULL args in remote query
	requiredArgs []string
}

// 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
	}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Point the @custom directive at a remote schema that exposes queries
  2. If you need a mutation, use @custom with mode MUTATION instead of QUERY
  3. Verify the remote's introspection returns a proper queryType (test with a GraphQL playground)

Example fix

// before
field: "addUser"
@custom(http: {url: "https://remote/mutationOnly", method: POST}, mode: QUERY)
// after
field: "addUser"
@custom(http: {url: "https://remote/mutationOnly", method: POST}, mode: MUTATION)
Defensive patterns

Strategy: validation

Validate before calling

const intro = await fetch(url, introspectionPost)
const schema = (await intro.json()).data?.__schema
if (!schema?.queryType) throw new Error('remote schema has no query type')

Type guard

func remoteHasQueries(i *introspectedSchema) bool {
  return i != nil && i.Data != nil && i.Data.Schema != nil && i.Data.Schema.QueryType != nil
}

Try / catch

err := schema.ValidateCustom(dgSchema, gqlSchema)
if err != nil && strings.Contains(err.Error(), "doesn't have any queries") {
  // switch the @custom directive to mode MUTATION or point to a query-capable remote
}

Prevention

When it happens

Trigger: Adding a @custom directive pointing at a remote GraphQL endpoint whose schema only defines mutations (or the introspection result has queryType: null), then running schema update/validation via validateRemoteGraphql.

Common situations: Pointing @custom at a mutation-only remote service; misconfigured URL hitting the wrong endpoint; a remote server with disabled introspection returning a schema stub without queryType.

Related errors


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