github/github-mcp-server · error
each issue_fields item must be an object
Error message
each issue_fields item must be an object
What it means
optionalIssueWriteFields (pkg/github/issues.go:246) validates the issue_fields argument of issue write tools. This error fires when issue_fields IS an array ([]any from JSON) but one of its elements is not a JSON object — e.g. a bare string, number, or nested array. Each element must be a map like {"field_name": ..., "value": ...} or {"field_name": ..., "delete": true}.
Source
Thrown at pkg/github/issues.go:246
TextValue struct {
Field IssueFieldRef
Value githubv4.String
} `graphql:"... on IssueFieldTextValue"`
}
func optionalIssueWriteFields(args map[string]any) ([]issueWriteFieldInput, error) {
issueFieldsRaw, exists := args["issue_fields"]
if !exists {
return nil, nil
}
var inputMaps []map[string]any
switch v := issueFieldsRaw.(type) {
case []any:
for _, item := range v {
itemMap, ok := item.(map[string]any)
if !ok {
return nil, fmt.Errorf("each issue_fields item must be an object")
}
inputMaps = append(inputMaps, itemMap)
}
case []map[string]any:
inputMaps = v
default:
return nil, fmt.Errorf("issue_fields must be an array")
}
issueFields := make([]issueWriteFieldInput, 0, len(inputMaps))
for _, itemMap := range inputMaps {
fieldName, err := RequiredParam[string](itemMap, "field_name")
if err != nil || strings.TrimSpace(fieldName) == "" {
return nil, fmt.Errorf("field_name is required for each issue_fields item")
}
fieldOptionName, err := OptionalParam[string](itemMap, "field_option_name")
if err != nil {View on GitHub (pinned to 0ea1f775a7)
Solutions
- Make every issue_fields element an object with at least field_name: [{"field_name":"Priority","value":"P0"}]
- Re-read the tool's input schema: issue_fields is an array of objects
- If generating args programmatically, serialize a typed struct ([]issueWriteFieldInput) instead of hand-built any slices
Example fix
# before
{"issue_fields": ["Priority", "P0"]}
# after
{"issue_fields": [{"field_name": "Priority", "field_option_name": "P0"}]} Defensive patterns
Strategy: validation
Validate before calling
raw, ok := args["issue_fields"]
if !ok {
return nil // absent is fine
}
items, ok := raw.([]any)
if !ok {
return errors.New("issue_fields must be an array")
}
for _, item := range items {
if _, ok := item.(map[string]any); !ok {
return errors.New("each issue_fields item must be an object")
}
} Type guard
func isIssueFieldItem(v any) bool {
_, ok := v.(map[string]any)
return ok
} Prevention
- Serialize tool args from a typed struct ([]IssueFieldInput) instead of hand-built map[string]any
- When generating JSON args programmatically, run them through the tool's schema validator before submit
- Test the happy path once against a scratch repo so shape errors surface in dev, not prod
When it happens
Trigger: Calling update_issue (or create_issue) with issue_fields=["Priority"] or issue_fields=["field_name","value"] instead of issue_fields=[{"field_name":"Priority","value":"P0"}]; also LLM-generated tool args that confuse the array-of-objects schema with array-of-strings.
Common situations: MCP clients/agents reformatting the schema; hand-written JSON tool payloads; passing a comma-separated string list split into tokens.
Related errors
- issue_fields must be an array
- field_name is required for each issue_fields item
- value cannot be null for field %q
- issue field %q cannot specify 'delete' together with 'value'
- issue field %q cannot specify both value and field_option_na
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/e7e7e0ef7823e3c5.
Report an issue: GitHub.