{"record":{"id":"8b3a16b0c1928bbf","repo":"sansan0/TrendRadar","slug":"param-name-value-8b3a16","errorCode":null,"errorMessage":"{param_name} 必须是数字，无法解析: {value}","messagePattern":"(.+?) 必须是数字，无法解析: (.+?)","errorType":"validation","errorClass":"InvalidParameterError","httpStatus":null,"severity":"error","filePath":"mcp_server/utils/validators.py","lineNumber":124,"sourceCode":"    \"\"\"\n    将字符串解析为浮点数\n\n    Args:\n        value: 字符串值\n        param_name: 参数名（用于错误消息）\n\n    Returns:\n        解析后的浮点数\n\n    Raises:\n        InvalidParameterError: 解析失败\n    \"\"\"\n    value = value.strip()\n\n    try:\n        return float(value)\n    except ValueError:\n        raise InvalidParameterError(\n            f\"{param_name} 必须是数字，无法解析: {value}\",\n            suggestion=f\"请提供有效的数字值，如: 0.6, 3.0\"\n        )\n\n\ndef _parse_string_to_bool(value: str) -> bool:\n    \"\"\"\n    将字符串解析为布尔值\n\n    Args:\n        value: 字符串值\n\n    Returns:\n        解析后的布尔值\n    \"\"\"\n    value = value.strip().lower()\n\n    if value in ('true', '1', 'yes', 'on'):","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/sansan0/TrendRadar/blob/8ee26026ba6c11dec41a95fb3895a7162876caa1/mcp_server/utils/validators.py#L106-L142","documentation":"Raised by _parse_string_to_float when a string cannot be parsed as a float. It applies float(value) after a strip(); Python float() accepts scientific notation and inf/nan, so this fires only for genuinely non-numeric text. param_name identifies which numeric parameter (e.g. a threshold like min_score) failed.","triggerScenarios":"Passing a fractional parameter as \"high\", \"0,6\" (comma decimal separator), \"60%\", or \"<0.6\". Any float-typed tool argument serialized as a string with formatting or units attached.","commonSituations":"European locale decimal commas; LLM-generated values with units or comparison operators; percent signs copied from UI; empty strings from optional fields.","solutions":["Send a plain decimal number: 0.6 or \"0.6\" (dot as decimal separator)","Remove units, percent signs, and comparison operators before sending; convert 60% to 0.6 yourself","Use null/omit for empty optional numeric fields rather than \"\"","Catch InvalidParameterError and re-ask the user/LLM for a bare number"],"exampleFix":"// before\n{\"min_score\": \"0,6\"}\n// after\n{\"min_score\": 0.6}","handlingStrategy":"validation","validationCode":"function toFloat(v: unknown): number {\n  const n = Number(String(v).trim().replace(',', '.')); // locale comma -> dot\n  if (!Number.isFinite(n)) throw new Error('not numeric');\n  return n;\n}","typeGuard":"const isFloatLike = (v: unknown): boolean =>\n  typeof v === 'number' || /^-?\\d+(?:\\.\\d+)?$/.test(String(v).trim());","tryCatchPattern":"try { call({ min_score: s }); }\ncatch (e) {\n  if (/必须是数字/.test(e.message)) s = 0.6; // default and retry once\n  else throw e;\n}","preventionTips":["Normalize decimal separators before sending","Never attach units, %, or comparison operators to numeric params","Run Number.isFinite on computed numeric values before invoking"],"tags":["type-coercion","validation","float-parsing","locale"],"backgroundTag":null,"analyzedSha":"8ee26026ba6c11dec41a95fb3895a7162876caa1","analyzedAt":"2026-08-15T01:42:18.084Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}