{"record":{"id":"95456c58f9c5e814","repo":"HKUDS/Vibe-Trading","slug":"name-must-be-a-number-got-value-r","errorCode":null,"errorMessage":"{name} must be a number, got {value!r}","messagePattern":"(.+?) must be a number, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/strategy_discovery_tool.py","lineNumber":86,"sourceCode":"\ndef _coerce_int(value: Any, name: str, default: int) -> int:\n    \"\"\"Coerce an integer parameter; raise ``ValueError`` on bad input.\"\"\"\n    if value is None:\n        return default\n    if isinstance(value, bool):  # bool is an int subclass — reject explicitly\n        raise ValueError(f\"{name} must be an integer, got {value!r}\")\n    try:\n        return int(value)\n    except (TypeError, ValueError, OverflowError) as exc:\n        raise ValueError(f\"{name} must be an integer, got {value!r}\") from exc\n\n\ndef _coerce_opt_float(value: Any, name: str) -> float | None:\n    \"\"\"Coerce an optional numeric parameter; reject NaN/inf and bad types.\"\"\"\n    if value is None:\n        return None\n    if isinstance(value, bool):\n        raise ValueError(f\"{name} must be a number, got {value!r}\")\n    try:\n        result = float(value)\n    except (TypeError, ValueError, OverflowError) as exc:\n        raise ValueError(f\"{name} must be a number, got {value!r}\") from exc\n    if result != result or result in (float(\"inf\"), float(\"-inf\")):\n        raise ValueError(f\"{name} must be a finite number, got {value!r}\")\n    return result\n\n\ndef _coerce_opt_str(value: Any, name: str) -> str | None:\n    \"\"\"Coerce an optional string parameter; blank/None become ``None``.\"\"\"\n    if value is None:\n        return None\n    if not isinstance(value, str):\n        raise ValueError(f\"{name} must be a string, got {value!r}\")\n    if len(value) > _MAX_STRING_PARAM_CHARS:\n        raise ValueError(\n            f\"{name} is too long ({len(value)} chars; \"","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/strategy_discovery_tool.py#L68-L104","documentation":"strategy_discovery_tool._coerce_opt_float validates optional numeric parameters. It first rejects booleans: since bool is not a valid numeric type for this tool, passing True/False for a float parameter raises ValueError naming the parameter. NaN/inf are rejected later in a separate check.","triggerScenarios":"Passing True or False for an optional numeric parameter, e.g. execute(min_sharpe=True); model-emitted JSON with a boolean in a number field.","commonSituations":"LLM tool-call schemas confusing numeric thresholds with flags; truthy shorthand like passing `use_filter and 0.5` which evaluates to a bool; UI toggles wired to numeric inputs.","solutions":["Pass a real number (e.g. 0.5) or None to omit","Fix the calling schema/typing so the field is number|nullable, not boolean","Audit upstream serialization that may coerce 0/1 to false/true (e.g. some JSON Schema validators)"],"exampleFix":"# before\ntool.execute(min_sharpe=True)\n# after\ntool.execute(min_sharpe=1.0)","handlingStrategy":"type-guard","validationCode":"if value is not None and isinstance(value, bool):\n    raise ValueError(f\"{name} must be a number, not a boolean\")\ntool.execute(**{name: value})","typeGuard":"def is_number_arg(v) -> bool:\n    return v is None or (isinstance(v, (int, float)) and not isinstance(v, bool))","tryCatchPattern":null,"preventionTips":["Keep numeric thresholds as numbers in your config, never flags","Check isinstance(x, bool) before numeric params"],"tags":["strategy-discovery","type-coercion","boolean-number","validation"],"backgroundTag":"invalid-argument-type","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}