github/github-mcp-server · error
field %q is TEXT; value must be a string
Error message
field %q is TEXT; value must be a string
What it means
Raised by convertProjectFieldValue (pkg/github/projects_batch.go:580) after the target field was resolved and found to have DataType "TEXT", but the supplied value is not a Go string (number, bool, array, object, or null). The library only wraps values into ProjectV2FieldValue.Text for strings. When this fires during pre-flight conversion the whole batch fails before any write; per-item occurrences surface as item errors.
Source
Thrown at pkg/github/projects_batch.go:580
candidates := make([]any, 0, len(fields))
for _, field := range fields {
candidates = append(candidates, map[string]any{
"id": field.ID,
"name": field.Name,
"data_type": field.DataType,
})
}
return candidates
}
func convertProjectFieldValue(field *ResolvedField, raw any) (githubv4.ProjectV2FieldValue, error) {
var zero githubv4.ProjectV2FieldValue
switch field.DataType {
case "TEXT":
s, ok := raw.(string)
if !ok {
return zero, fmt.Errorf("field %q is TEXT; value must be a string", field.Name)
}
v := githubv4.String(s)
return githubv4.ProjectV2FieldValue{Text: &v}, nil
case "NUMBER":
f, ok := toFloat64(raw)
if !ok {
return zero, fmt.Errorf("field %q is NUMBER; value must be a number", field.Name)
}
v := githubv4.Float(f)
return githubv4.ProjectV2FieldValue{Number: &v}, nil
case "DATE":
s, ok := raw.(string)
if !ok {
return zero, fmt.Errorf("field %q is DATE; value must be a YYYY-MM-DD string", field.Name)
}
t, err := time.Parse("2006-01-02", s)View on GitHub (pinned to 0ea1f775a7)
Solutions
- Send the value as a string: "value": "123" instead of 123
- If you meant to clear the field, use the clear operation/update_project_item, not a null value here
- Check the field's data type first (list_project_fields) and shape values to match
- For values from dynamic sources, stringify numbers/booleans before building the payload
Example fix
// before (field "Size" is TEXT)
{"updated_field": {"name": "Size", "value": 42}}
// after
{"updated_field": {"name": "Size", "value": "42"}} Defensive patterns
Strategy: type-guard
Validate before calling
// After resolving field metadata, gate the value on DataType
switch field.DataType {
case "TEXT":
if _, ok := value.(string); !ok {
return fmt.Errorf("field %s is TEXT: stringify the value", field.Name)
}
} Type guard
func matchesFieldType(dataType string, v any) bool {
switch dataType {
case "TEXT", "DATE", "SINGLE_SELECT", "ITERATION":
s, ok := v.(string); return ok && s != ""
case "NUMBER":
switch v.(type) {
case float64, int, int64: return true
}
return false
}
return false
} Prevention
- Fetch the field's data_type once per run and coerce values to it before batching
- Stringify numeric-looking text ("42") and never send bools to text fields
- To clear a field, use the clear operation — null values are not the clear path here
When it happens
Trigger: A Project V2 text field (e.g. "Notes", "Status" text field) updated with "value": 123, true, null, or ["a","b"]. The field's data type comes from GitHub, so the mismatch is purely on the caller's side.
Common situations: Numeric-looking text (ticket numbers, sizes) sent unquoted from JSON numbers; booleans for flags; a schema-less client forwarding whatever type the source column had; null intended to clear a field (this tool does not clear — that is a different operation).
Related errors
- field %q is NUMBER; value must be a number
- node_id must be a non-empty string
- item_id: %w
- %s must be a non-empty string
- %s must be a positive integer: %w
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/e0bf7cc57c14b911.
Report an issue: GitHub.