{"record":{"id":"c10dae8231d473fe","repo":"github/github-mcp-server","slug":"expected-number-got-t","errorCode":null,"errorMessage":"expected number, got %T","messagePattern":"expected number, got %T","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/github/params.go","lineNumber":78,"sourceCode":"\treturn errors.As(err, &acceptedError)\n}\n\n// toInt converts a value to int, handling both float64 and string representations.\n// Some MCP clients send numeric values as strings. It rejects NaN, ±Inf,\n// fractional values, and values outside the int range.\nfunc toInt(val any) (int, error) {\n\tvar f float64\n\tswitch v := val.(type) {\n\tcase float64:\n\t\tf = v\n\tcase string:\n\t\tvar err error\n\t\tf, err = strconv.ParseFloat(v, 64)\n\t\tif err != nil {\n\t\t\treturn 0, fmt.Errorf(\"invalid numeric value: %s\", v)\n\t\t}\n\tdefault:\n\t\treturn 0, fmt.Errorf(\"expected number, got %T\", val)\n\t}\n\tif math.IsNaN(f) || math.IsInf(f, 0) {\n\t\treturn 0, fmt.Errorf(\"non-finite numeric value\")\n\t}\n\tif f != math.Trunc(f) {\n\t\treturn 0, fmt.Errorf(\"non-integer numeric value: %v\", f)\n\t}\n\tif f > math.MaxInt || f < math.MinInt {\n\t\treturn 0, fmt.Errorf(\"numeric value out of int range: %v\", f)\n\t}\n\treturn int(f), nil\n}\n\n// toInt64 converts a value to int64, handling both float64 and string representations.\n// Some MCP clients send numeric values as strings. It rejects NaN, ±Inf,\n// fractional values, and values that lose precision in the float64→int64 conversion.\nfunc toInt64(val any) (int64, error) {\n\tvar f float64","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/params.go#L60-L96","documentation":"Thrown by toInt in pkg/github/params.go when a value destined for an int parameter is neither a float64 (JSON number) nor a string — i.e. a bool, array, or object. JSON decodes numbers to float64, so this error means the argument is structurally the wrong kind of value, not just malformed text.","triggerScenarios":"per_page: true, page: [1], or per_page: {\"value\": 30} passed to an int-typed parameter of a tool like list_issues or list_pull_requests.","commonSituations":"LLMs answering a numeric field with true/false; clients passing a single-element array; nested objects produced by double-wrapping of the arguments payload; boolean flags mistakenly reused for numeric fields.","solutions":["Pass a plain JSON number (or numeric string) for the parameter.","Unwrap single-element arrays before sending.","Check the tool's inputSchema for the exact expected type of the failing parameter.","Enable client-side JSON schema validation of tool arguments before dispatch."],"exampleFix":"// before\narguments: { owner, repo, per_page: [30] }\n// after\narguments: { owner, repo, per_page: 30 }","handlingStrategy":"type-guard","validationCode":"function assertScalarNumber(name, v) {\n  if (v !== undefined && typeof v !== \"number\" && typeof v !== \"string\") {\n    throw new Error(`${name} must be number or numeric string, got ${typeof v}`);\n  }\n}","typeGuard":"function isNumberLike(v: unknown): v is number | string {\n  return (typeof v === \"number\" && Number.isFinite(v)) ||\n         (typeof v === \"string\" && v.trim() !== \"\" && !isNaN(Number(v)));\n}","tryCatchPattern":"On 'expected number, got bool/array/map', correct the argument shape client-side (unwrap arrays, extract scalar fields) and retry once.","preventionTips":["Do not forward raw form or LLM payloads into tool arguments; map fields explicitly.","Reject true/false and objects for numeric fields at your boundary.","Log the full arguments object on failure to spot structural mistakes quickly."],"tags":["validation","type-mismatch","numeric","argument-parsing","mcp-tool"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}