{"record":{"id":"7d0bf51194e28e90","repo":"HKUDS/Vibe-Trading","slug":"name-must-be-an-integer-got-value-r","errorCode":null,"errorMessage":"{name} must be an integer, got {value!r}","messagePattern":"(.+?) must be an integer, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/tools/strategy_discovery_tool.py","lineNumber":74,"sourceCode":"\ndef _envelope(result: Any) -> str:\n    \"\"\"Serialize a facade envelope defensively.\n\n    The facade contract returns ``{\"status\": \"ok\", ...}`` or\n    ``{\"status\": \"error\", \"error\": ...}`` dicts; anything else is wrapped\n    so the agent always receives parseable JSON.\n    \"\"\"\n    if not isinstance(result, dict):\n        result = {\"status\": \"ok\", \"result\": result}\n    return json.dumps(result, ensure_ascii=False)\n\n\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}\")","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/tools/strategy_discovery_tool.py#L56-L92","documentation":"strategy_discovery_tool._coerce_int rejects values that are not coercible to int. bools are rejected explicitly (True/False would otherwise pass as 1/0 since bool subclasses int), and this branch is the bool check: any boolean value for an integer parameter raises immediately. The message names the parameter and shows the offending value.","triggerScenarios":"Passing True/False for an int parameter, e.g. execute(limit=True) or limit=False; JSON tool args where the model emitted a boolean for a numeric field.","commonSituations":"LLM tool-call schemas mapping \"top_n\" to a checkbox-like boolean; upstream code passing flags into count parameters; Python truthiness habits like passing `if x else 0` results that yield True.","solutions":["Pass an actual integer (e.g. 10) instead of a boolean","If the boolean came from a schema mismatch, fix the tool-call schema so the field is typed integer","For optional params, pass None to get the default instead of True/False"],"exampleFix":"# before\ntool.execute(top_n=True)\n# after\ntool.execute(top_n=10)","handlingStrategy":"type-guard","validationCode":"assert not isinstance(value, bool), f\"{name} must be int, not bool\"\ntool.execute(**{name: value})","typeGuard":"def is_int_arg(v) -> bool:\n    return not isinstance(v, bool) and (\n        isinstance(v, int) or (isinstance(v, str) and v.strip().lstrip(\"+-\").isdigit())\n    )","tryCatchPattern":null,"preventionTips":["Type tool-call schemas as integer, never boolean, for count params","Lint for bools passed to int parameters in your orchestration layer"],"tags":["strategy-discovery","type-coercion","boolean-int","validation"],"backgroundTag":"invalid-argument-type","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}