github/github-mcp-server · error

updated_field must be an object

Error message

updated_field must be an object

What it means

Raised by parseBatchFieldSpec (pkg/github/projects_batch.go:505) when the top-level updated_field argument is not a JSON object — it is a string, number, array, boolean, or null. updated_field is mandatory for update_project_items and must be an object with a value key and exactly one of id or name. This fails the entire request before any item is processed.

Source

Thrown at pkg/github/projects_batch.go:505

		return 0, err
	}
	if n <= 0 {
		return 0, fmt.Errorf("value must be greater than zero (got %d)", n)
	}
	return n, nil
}

type batchFieldSpec struct {
	id    int64
	name  string
	value any
}

func parseBatchFieldSpec(raw any) (batchFieldSpec, error) {
	var spec batchFieldSpec
	input, ok := raw.(map[string]any)
	if !ok || input == nil {
		return spec, fmt.Errorf("updated_field must be an object")
	}

	value, hasValue := input["value"]
	if !hasValue {
		return spec, fmt.Errorf("updated_field.value is required")
	}
	spec.value = value

	idField, hasID := input["id"]
	nameField, hasName := input["name"]
	switch {
	case hasID && hasName:
		return spec, fmt.Errorf("updated_field must set either id or name, not both")
	case !hasID && !hasName:
		return spec, fmt.Errorf("updated_field requires either id or name")
	case hasID:
		id, err := validatePositiveInt64(idField)
		if err != nil {

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Wrap the field spec in an object: {"updated_field": {"name": "Status", "value": "Done"}}
  2. Check the tool's input schema — updated_field is a single object applied to every item in the batch
  3. If you meant different fields per item, that is unsupported: split into one call per field
  4. Validate that updated_field decodes to map[string]any before sending

Example fix

// before
{"updated_field": "Status", ...}
// after
{"updated_field": {"name": "Status", "value": "Done"}, "items": [...]}
Defensive patterns

Strategy: validation

Validate before calling

spec, ok := args["updated_field"].(map[string]any)
if !ok || spec == nil {
	return fmt.Errorf("updated_field must be an object with name/id and value")
}

Type guard

func isFieldSpecObject(v any) bool { m, ok := v.(map[string]any); return ok && m != nil }

Prevention

When it happens

Trigger: "updated_field": "Status", "updated_field": null, "updated_field": ["Status", "Done"], or passing the value directly as "updated_field": {"name":"Status","value":"Done"} is correct but "updated_field": "name=Status" is not. Any non-map JSON value hits the failed type assertion at line 503.

Common situations: Misreading the schema and passing just the field name; older/newer tool versions where the argument shape changed; hand-built JSON payloads; MCP clients collapsing a one-property object to a bare string.

Related errors


AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15). Data as JSON: /api/errors/fa22884093efa26b. Report an issue: GitHub.