dgraph-io/dgraph · error

can't convert input to map

Error message

can't convert input to map

What it means

getRemoveNodeInput reads the 'input' argument of the removeNode admin mutation and, like moveTablet, requires it to be a map[string]interface{}. If the argument cannot be type-asserted to a map, inputArgError wraps this message and the mutation fails. It means the resolver never received a structured input object.

Source

Thrown at graphql/admin/removeNode.go:48

		return resolve.EmptyResult(m, err), false
	}

	if _, err = worker.RemoveNodeOverNetwork(ctx, &pb.RemoveNodeRequest{NodeId: input.NodeId,
		GroupId: input.GroupId}); err != nil {
		return resolve.EmptyResult(m, err), false
	}

	return resolve.DataResult(m,
		map[string]interface{}{m.Name(): response("Success",
			fmt.Sprintf("Removed node with group: %v, idx: %v", input.GroupId, input.NodeId))},
		nil,
	), true
}

func getRemoveNodeInput(m schema.Mutation) (*removeNodeInput, error) {
	inputArg, ok := m.ArgValue(schema.InputArgName).(map[string]interface{})
	if !ok {
		return nil, inputArgError(errors.Errorf("can't convert input to map"))
	}

	inputRef := &removeNodeInput{}
	nodeId, err := parseAsUint64(inputArg["nodeId"])
	if err != nil {
		return nil, inputArgError(schema.GQLWrapf(err, "can't convert input.nodeId to uint64"))
	}
	inputRef.NodeId = nodeId

	gId, err := parseAsUint32(inputArg["groupId"])
	if err != nil {
		return nil, inputArgError(schema.GQLWrapf(err, "can't convert input.groupId to uint32"))
	}
	inputRef.GroupId = gId

	return inputRef, nil
}

View on GitHub (pinned to 759e242be6)

Solutions

  1. Send input as an object: { removeNode(input: { nodeId: 1 }) }.
  2. When using variables, declare $input: RemoveNodeInput! and supply a JSON object in the variables payload.
  3. Confirm the argument key is 'input' and the input type name matches the current admin schema.
  4. Log/inspect the outgoing request body; ensure the input field is a JSON object, not a quoted string.
  5. Regenerate client bindings from the live schema if the mutation signature changed after an upgrade.

Example fix

// before
mutation { removeNode(nodeId: 1) { response { message } } }
// after
mutation { removeNode(input: { nodeId: 1 }) { response { message } } }
Defensive patterns

Strategy: validation

Validate before calling

function assertRemoveNodeInput(v) {
  if (v === null || typeof v !== 'object' || Array.isArray(v)) {
    throw new Error('removeNode input must be an object like {nodeId}');
  }
  return v;
}

Type guard

function isPlainObject(v) { return v !== null && typeof v === 'object' && !Array.isArray(v); }

Try / catch

try {
  await gql(`mutation Rm($input: RemoveNodeInput!){ removeNode(input: $input){...} }`, { input });
} catch (e) {
  if (String(e.message).includes("can't convert input to map")) {
    // rebuild input as a proper object and retry once
  }
}

Prevention

When it happens

Trigger: Calling removeNode with a missing/misnamed input argument, a scalar instead of an object, or via a raw client that bypasses GraphQL coercion so ArgValue is not a map.

Common situations: Hand-written admin mutations omitting the input wrapper ({ removeNode(nodeId: 1) } instead of { removeNode(input: { nodeId: 1 }) }), GraphQL variables typed as a string or number instead of an object, or outdated client SDKs predating the input-object signature.

Related errors


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