github/github-mcp-server · error
non-integer numeric value: %v
Error message
non-integer numeric value: %v
What it means
Thrown by toInt in pkg/github/params.go when a numeric value has a fractional part (f != math.Trunc(f)). Int-typed tool parameters (page, per_page, issue_number, etc.) must be whole numbers even when sent as strings or JSON floats.
Source
Thrown at pkg/github/params.go:84
func toInt(val any) (int, error) {
var f float64
switch v := val.(type) {
case float64:
f = v
case string:
var err error
f, err = strconv.ParseFloat(v, 64)
if err != nil {
return 0, fmt.Errorf("invalid numeric value: %s", v)
}
default:
return 0, fmt.Errorf("expected number, got %T", val)
}
if math.IsNaN(f) || math.IsInf(f, 0) {
return 0, fmt.Errorf("non-finite numeric value")
}
if f != math.Trunc(f) {
return 0, fmt.Errorf("non-integer numeric value: %v", f)
}
if f > math.MaxInt || f < math.MinInt {
return 0, fmt.Errorf("numeric value out of int range: %v", f)
}
return int(f), nil
}
// toInt64 converts a value to int64, handling both float64 and string representations.
// Some MCP clients send numeric values as strings. It rejects NaN, ±Inf,
// fractional values, and values that lose precision in the float64→int64 conversion.
func toInt64(val any) (int64, error) {
var f float64
switch v := val.(type) {
case float64:
f = v
case string:
var err error
f, err = strconv.ParseFloat(v, 64)View on GitHub (pinned to 0ea1f775a7)
Solutions
- Round or floor the value client-side and send a whole number.
- Check for stray decimals in string-form numbers, including thousands separators like "1.000" (parsed as 1.0, which is integral, but "1.5" fails).
- Use Math.round/Math.floor deliberately, not implicit string coercion.
Example fix
// before
const perPage = totalItems / maxPages; // e.g. 27.5
arguments = { owner, repo, per_page: perPage };
// after
const perPage = Math.ceil(totalItems / maxPages);
arguments = { owner, repo, per_page: perPage }; Defensive patterns
Strategy: validation
Validate before calling
function intArg(name, v) {
const n = typeof v === "string" ? Number(v) : v;
if (typeof n !== "number" || !Number.isFinite(n) || !Number.isInteger(n)) {
throw new Error(`${name} must be an integer, got ${JSON.stringify(v)}`);
}
return n;
} Type guard
function isIntegerLike(v: unknown): v is number {
const n = typeof v === "string" ? Number(v) : v;
return typeof n === "number" && Number.isInteger(n);
} Try / catch
On 'non-integer numeric value: <v>', apply Math.round or Math.floor deliberately, then retry; do not blind-cast.
Prevention
- Round all computed pagination/count values before building arguments.
- Watch locale-formatted strings (commas/dots) in numeric fields.
- Unit-test client helpers that compute per_page/page with odd totals.
When it happens
Trigger: per_page: 30.5, page: 1.2, or per_page: "29.99" passed to an int parameter; averaged/computed pagination values forwarded without rounding.
Common situations: Client arithmetic producing floats (e.g. total/limit); spreadsheets or config files storing 30.0-style decimals; LLMs emitting decimal values for count fields.
Related errors
- invalid numeric value: %s
- expected number, got %T
- non-finite numeric value
- numeric value out of int range: %v
- parameter %s is not a valid number: %w
AI-assisted analysis of github/github-mcp-server@0ea1f775a7 (2026-08-15).
Data as JSON: /api/errors/1923adf4cd4ea613.
Report an issue: GitHub.