{"record":{"id":"fb9f4c7465f133f9","repo":"tirth8205/code-review-graph","slug":"unsupported-toml-value-type-value-r","errorCode":null,"errorMessage":"Unsupported TOML value: {type(value)!r}","messagePattern":"Unsupported TOML value: (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"code_review_graph/skills.py","lineNumber":433,"sourceCode":"    servers = parsed.get(\"mcpServers\")\n    if isinstance(servers, dict) and \"code-review-graph\" in servers:\n        print(\n            f\"  OpenCode: legacy config found at {legacy}; leaving it unchanged. \"\n            \"OpenCode now reads opencode.json or opencode.jsonc with a top-level \"\n            \"'mcp' setting.\"\n        )\n\n\ndef _format_toml_value(value: Any) -> str:\n    \"\"\"Format a primitive Python value as TOML.\"\"\"\n    if isinstance(value, str):\n        escaped = value.replace(\"\\\\\", \"\\\\\\\\\").replace('\"', '\\\\\"')\n        return f'\"{escaped}\"'\n    if isinstance(value, bool):\n        return \"true\" if value else \"false\"\n    if isinstance(value, list):\n        return \"[\" + \", \".join(_format_toml_value(item) for item in value) + \"]\"\n    raise TypeError(f\"Unsupported TOML value: {type(value)!r}\")\n\n\ndef _merge_toml_mcp_server(\n    config_path: Path,\n    server_name: str,\n    server_entry: dict[str, Any],\n    dry_run: bool = False,\n) -> bool:\n    \"\"\"Append a Codex MCP server section without clobbering the rest of the file.\"\"\"\n    section_header = f\"[mcp_servers.{server_name}]\"\n    existing = \"\"\n    if config_path.exists():\n        existing = config_path.read_text(encoding=\"utf-8\")\n        if section_header in existing:\n            return False\n\n    section_lines = [section_header]\n    for key, value in server_entry.items():","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/tirth8205/code-review-graph/blob/b58668751ab0c7670c078cf7cbd4d1f5b8e54f81/code_review_graph/skills.py#L415-L451","documentation":"_format_toml_value() serializes strings, bools, and (recursively) lists of those; any other type — int, float, dict, None, datetime — hits the final TypeError. It exists to keep generated TOML (e.g. merged MCP server blocks) strictly within the supported subset.","triggerScenarios":"Passing a config dict to _merge_toml_mcp_server whose values include numbers, nulls, nested tables (dicts), or any non-str/bool/list type — for example command port: 8080 or an env entry with a null value.","commonSituations":"Hand-written config dicts using JSON/YAML idioms (ints for ports, nulls for optional keys); data loaded from JSON with numeric scalars; newer config schemas adding typed values the formatter was never taught.","solutions":["Convert numeric values to strings before merging (str(port)) — quickest fix at the call site.","Strip None values from the dict (or map them to empty strings) before passing it in.","If you control the library, extend _format_toml_value with int/float branches: return str(value)."],"exampleFix":"# before\nserver_entry = {\"command\": \"uvx\", \"args\": [\"crg\"], \"port\": 8080}\n_merge_toml_mcp_server(path, \"crg\", server_entry)\n# after\nserver_entry = {\"command\": \"uvx\", \"args\": [\"crg\"], \"port\": \"8080\"}\n_merge_toml_mcp_server(path, \"crg\", server_entry)","handlingStrategy":"type-guard","validationCode":"def coerce_toml_scalars(value):\n    if isinstance(value, (int, float)) and not isinstance(value, bool):\n        return str(value)\n    if value is None:\n        return \"\"\n    if isinstance(value, dict):\n        return {k: coerce_toml_scalars(v) for k, v in value.items()}\n    if isinstance(value, list):\n        return [coerce_toml_scalars(v) for v in value]\n    return value\nserver_entry = coerce_toml_scalars(server_entry)","typeGuard":"def is_toml_formattable(value) -> bool:\n    if isinstance(value, bool) or isinstance(value, str):\n        return True\n    if isinstance(value, list):\n        return all(is_toml_formattable(v) for v in value)\n    return False","tryCatchPattern":"try:\n    _merge_toml_mcp_server(config_path, name, server_entry)\nexcept TypeError as exc:\n    if \"Unsupported TOML value\" in str(exc):\n        server_entry = {k: str(v) if isinstance(v, (int, float)) else v for k, v in server_entry.items()}\n        _merge_toml_mcp_server(config_path, name, server_entry)","preventionTips":["Keep MCP server config values as strings/bools only; stringify ports and numbers.","Reject or strip None values before merging config into TOML.","Add a test asserting every value in generated server entries passes the formatter."],"tags":["toml","config-serialization","type-error"],"backgroundTag":"unsupported-config-value-type","analyzedSha":"b58668751ab0c7670c078cf7cbd4d1f5b8e54f81","analyzedAt":"2026-08-28T13:19:08.966Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}