github/github-mcp-server · error

item_id: %w

Error message

item_id: %w

What it means

Raised by parseItemRef (pkg/github/projects_batch.go:423) when item_id fails validatePositiveInt64. The underlying wrapped error (from pkg/github/projects.go:2320 and :484) is one of: 'value must be a number (got string/bool/nil)' for non-numeric JSON values, 'value must be a valid integer' for fractional floats like 1.5, or 'value must be greater than zero' for 0/negative. The item is rejected as 'invalid_item_ref'.

Source

Thrown at pkg/github/projects_batch.go:423

	switch {
	case formsPresent == 0:
		return fmt.Errorf("each item requires exactly one of node_id, item_id, or item_owner + item_repo + issue_number")
	case formsPresent > 1:
		return fmt.Errorf("each item must set exactly one of node_id, item_id, or item_owner + item_repo + issue_number, not more than one")
	}

	switch {
	case hasNodeID:
		s, ok := entry["node_id"].(string)
		if !ok || s == "" {
			return fmt.Errorf("node_id must be a non-empty string")
		}
		p.refKind = batchRefNodeID
		p.nodeID = s
	case hasItemID:
		id, err := validatePositiveInt64(entry["item_id"])
		if err != nil {
			return fmt.Errorf("item_id: %w", err)
		}
		p.refKind = batchRefItemID
		p.itemID = id
	default:
		issueOwner, ownerErr := stringFromEntry(entry, "item_owner")
		issueRepo, repoErr := stringFromEntry(entry, "item_repo")
		issueNumber, numErr := intFromEntry(entry, "issue_number")
		for _, err := range []error{ownerErr, repoErr, numErr} {
			if err != nil {
				return fmt.Errorf("item_owner, item_repo, and issue_number must all be provided together: %w", err)
			}
		}
		p.refKind = batchRefIssue
		p.issueOwner = issueOwner
		p.issueRepo = issueRepo
		p.issueNumber = issueNumber
	}
	return nil

View on GitHub (pinned to 0ea1f775a7)

Solutions

  1. Send item_id as an unquoted positive integer: {"item_id": 12345678}
  2. If the ID arrives as a string, parse it to an int before building the request (do not forward it raw)
  3. Guard against 0/null defaults before adding an item to the batch
  4. If the value is actually a node ID string like "PVTI_...", use node_id instead

Example fix

// before
{"items": [{"item_id": "12345678"}]}
// after
{"items": [{"item_id": 12345678}]}
Defensive patterns

Strategy: validation

Validate before calling

if v, ok := entry["item_id"]; ok {
	f, isNum := v.(float64) // JSON numbers decode to float64
	if !isNum || f != float64(int64(f)) || int64(f) <= 0 {
		return fmt.Errorf("item_id must be a positive integer (got %v)", v)
	}
}

Type guard

func isPositiveJSONInt(v any) bool { f, ok := v.(float64); return ok && f == float64(int64(f)) && int64(f) > 0 }

Prevention

When it happens

Trigger: {"item_id": "123456"} (quoted string), {"item_id": 1.5} or 1e9-with-fraction from JSON decoding, {"item_id": 0}, {"item_id": -5}, or {"item_id": null}. Only Go float64/int64/int are accepted — every JSON number decodes as float64 and must be integral.

Common situations: IDs quoted when serialized from a database or CSV; a default zero value leaking from a struct; nulls from optional columns; clients that send IDs as strings for precision safety elsewhere.

Related errors


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