{"record":{"id":"3d4b60f8a41c00f2","repo":"github/copilot-sdk","slug":"parameter-param-name-expected-a-numeric-3d4b60","errorCode":null,"errorMessage":"Parameter ' + param.name() + ' expected a numeric value for OptionalDouble, got: + raw.getClass().getSimpleName()","messagePattern":"Parameter ' \\+ param\\.name\\(\\) \\+ ' expected a numeric value for OptionalDouble, got: \\+ raw\\.getClass\\(\\)\\.getSimpleName\\(\\)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"java/sdk/src/main/java/com/github/copilot/rpc/ParamCoercion.java","lineNumber":98,"sourceCode":"                return (T) java.util.OptionalInt.of(((Number) raw).intValue());\n            } catch (ClassCastException ex) {\n                throw new IllegalArgumentException(\"Parameter '\" + param.name()\n                        + \"' expected a numeric value for OptionalInt, got: \" + raw.getClass().getSimpleName(), ex);\n            }\n        }\n        if (type == java.util.OptionalLong.class) {\n            try {\n                return (T) java.util.OptionalLong.of(((Number) raw).longValue());\n            } catch (ClassCastException ex) {\n                throw new IllegalArgumentException(\"Parameter '\" + param.name()\n                        + \"' expected a numeric value for OptionalLong, got: \" + raw.getClass().getSimpleName(), ex);\n            }\n        }\n        if (type == java.util.OptionalDouble.class) {\n            try {\n                return (T) java.util.OptionalDouble.of(((Number) raw).doubleValue());\n            } catch (ClassCastException ex) {\n                throw new IllegalArgumentException(\"Parameter '\" + param.name()\n                        + \"' expected a numeric value for OptionalDouble, got: \" + raw.getClass().getSimpleName(), ex);\n            }\n        }\n\n        try {\n            return mapper.convertValue(raw, type);\n        } catch (IllegalArgumentException ex) {\n            throw new IllegalArgumentException(\n                    \"Failed to coerce parameter '\" + param.name() + \"' to type \" + type.getSimpleName(), ex);\n        }\n    }\n\n    /**\n     * Parses a {@link Param}'s string default value into the declared Java type.\n     *\n     * <p>\n     * Handles primitives, boxed types, {@link String}, {@link Boolean}, and enums\n     * explicitly, mirroring the validation logic in {@link Param}. The","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/java/sdk/src/main/java/com/github/copilot/rpc/ParamCoercion.java#L80-L116","documentation":"Thrown by ParamCoercion.coerce when an RPC parameter declared as java.util.OptionalDouble receives a value that is not a java.lang.Number. The coercion attempts ((Number) raw).doubleValue() and wraps the ClassCastException into an IllegalArgumentException naming the parameter and the actual runtime class.","triggerScenarios":"Calling a tool with an OptionalDouble parameter but supplying a String (e.g. \"3.14\"), Boolean, or collection — typically from hand-built argument maps or lenient JSON deserialization.","commonSituations":"Numeric values passed as JSON strings; config files quoting numbers; clients using a different locale/format (\"3,14\") or sending integers-as-strings.","solutions":["Pass a java.lang.Number (Double/BigDecimal) for OptionalDouble parameters, or null/omit for empty","Convert strings first: OptionalDouble.of(Double.parseDouble(String.valueOf(raw)))","Verify the tool parameter schema and send properly typed JSON numbers (unquoted)","Catch IllegalArgumentException, inspect the parameter name and runtime class reported in the message, and fix the payload"],"exampleFix":"// before\nargs.put(\"rate\", \"0.25\"); // String\ntool.invoke(args); // throws: expected a numeric value for OptionalDouble, got: String\n// after\nargs.put(\"rate\", 0.25d);\ntool.invoke(args);","handlingStrategy":"type-guard","validationCode":"if (raw instanceof Number) { args.put(\"rate\", ((Number) raw).doubleValue()); }","typeGuard":"boolean isNumber(Object v) { return v instanceof Number; }","tryCatchPattern":"try { tool.invoke(args); } catch (IllegalArgumentException e) { if (e.getMessage().contains(\"OptionalDouble\")) { /* convert to Double and retry */ } else { throw e; } }","preventionTips":["Never send numbers as quoted JSON strings","Parse numeric config values into Double/BigDecimal up front","Validate against the tool parameter schema before invocation"],"tags":["java","rpc","type-mismatch","parameters"],"backgroundTag":"type-mismatch","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}