{"record":{"id":"78e0232134defc7e","repo":"github/github-mcp-server","slug":"each-field-filters-entry-must-be-an-object","errorCode":null,"errorMessage":"each field_filters entry must be an object","messagePattern":"each field_filters entry must be an object","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/github/issues.go","lineNumber":3070,"sourceCode":"\tValue string\n}\n\n// parseRawFieldFilters extracts the optional field_filters parameter into a list of\n// {name, value} pairs. The value is always a string here; type-aware coercion happens\n// later in resolveFieldFilters once we know each field's data_type.\nfunc parseRawFieldFilters(args map[string]any) ([]rawFieldFilter, error) {\n\traw, ok := args[\"field_filters\"]\n\tif !ok {\n\t\treturn nil, nil\n\t}\n\n\tvar entries []map[string]any\n\tswitch v := raw.(type) {\n\tcase []any:\n\t\tfor _, f := range v {\n\t\t\tentry, ok := f.(map[string]any)\n\t\t\tif !ok {\n\t\t\t\treturn nil, fmt.Errorf(\"each field_filters entry must be an object\")\n\t\t\t}\n\t\t\tentries = append(entries, entry)\n\t\t}\n\tcase []map[string]any:\n\t\tentries = v\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"field_filters must be an array\")\n\t}\n\n\tfilters := make([]rawFieldFilter, 0, len(entries))\n\tfor _, entry := range entries {\n\t\tfieldName, err := RequiredParam[string](entry, \"field_name\")\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"field_filters entry: %s\", err.Error())\n\t\t}\n\t\tvalue, err := RequiredParam[string](entry, \"value\")\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"field_filters entry %q: %s\", fieldName, err.Error())","sourceCodeStart":3052,"sourceCodeEnd":3088,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/issues.go#L3052-L3088","documentation":"parseRawFieldFilters rejects a field_filters array in which at least one element is not a JSON object. Each entry must be an object like {\"field_name\":\"Status\",\"value\":\"Bug\"} so field_name and value can be extracted.","triggerScenarios":"Calling an issue-listing tool with field_filters set to an array containing a bare string, number, or null, e.g. [\"Status\"] or [123].","commonSituations":"An LLM collapses the filter to a string (\"field_filters\":[\"Status=Bug\"]); a script reuses a key=value syntax instead of object form.","solutions":["Make every element of field_filters an object with field_name and value string keys","Remove stray non-object entries from the array"],"exampleFix":"// before\n{\"field_filters\":[\"Priority=P1\"]}\n// after\n{\"field_filters\":[{\"field_name\":\"Priority\",\"value\":\"P1\"}]}","handlingStrategy":"validation","validationCode":"func validateFieldFiltersShape(raw any) error {\n\tlist, ok := raw.([]any)\n\tif !ok {\n\t\treturn fmt.Errorf(\"field_filters must be an array\")\n\t}\n\tfor i, f := range list {\n\t\tif _, ok := f.(map[string]any); !ok {\n\t\t\treturn fmt.Errorf(\"field_filters[%d] must be an object\", i)\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func isFieldFilterList(v any) bool {\n\tlist, ok := v.([]any)\n\tif !ok {\n\t\treturn false\n\t}\n\tfor _, f := range list {\n\t\tif _, ok := f.(map[string]any); !ok {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","tryCatchPattern":null,"preventionTips":["Always build field_filters as an array of objects, never a bare string or map","Add a schema check in your tool-invocation wrapper rejecting non-object entries"],"tags":["validation","field-filters","issues","input-shape"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}