{"record":{"id":"53b5bd43ce740fd0","repo":"Panniantong/Agent-Reach","slug":"mcporter-utf-8-json","errorCode":null,"errorMessage":"mcporter 配置不是有效的 UTF-8 JSON","messagePattern":"mcporter 配置不是有效的 UTF-8 JSON","errorType":"exception","errorClass":"McporterConfigError","httpStatus":null,"severity":"error","filePath":"agent_reach/channels/mcporter.py","lineNumber":127,"sourceCode":"\ndef _read_config_object(config_path: Path) -> dict:\n    try:\n        raw = read_small_text_no_follow(\n            config_path,\n            max_bytes=_MAX_CONFIG_BYTES,\n        )\n    except PrivatePathError as exc:\n        raise McporterConfigError(\n            f\"mcporter 配置文件无法安全读取：{exc}\"\n        ) from exc\n    except (OSError, UnicodeError) as exc:\n        raise McporterConfigError(\"mcporter 配置文件无法安全读取\") from exc\n    if raw is None:\n        raise McporterConfigError(\"mcporter 配置文件不存在\")\n    try:\n        payload = json.loads(raw)\n    except json.JSONDecodeError as exc:\n        raise McporterConfigError(\"mcporter 配置不是有效的 UTF-8 JSON\") from exc\n    if not isinstance(payload, dict):\n        raise McporterConfigError(\"mcporter 配置顶层必须是对象\")\n    return payload\n\n\ndef configured_server_names(output: str) -> set[str]:\n    \"\"\"Return exact configured server names from ``mcporter ... --json``.\n\n    Paths, descriptions, endpoints, and other metadata are deliberately\n    ignored: only each server object's ``name`` field is a routing signal.\n    \"\"\"\n    try:\n        payload = json.loads(output)\n    except (json.JSONDecodeError, TypeError) as exc:\n        raise McporterConfigError(\"mcporter 返回的 JSON 无法解析\") from exc\n\n    if not isinstance(payload, dict) or not isinstance(payload.get(\"servers\"), list):\n        raise McporterConfigError(\"mcporter JSON 缺少 servers 列表\")","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/Panniantong/Agent-Reach/blob/93ae1d18c37b707dec053c7c4f9d91cd8ef8943d/agent_reach/channels/mcporter.py#L109-L145","documentation":"Raised when json.loads() on the read mcporter config text raises JSONDecodeError. The bytes were read and UTF-8-decoded fine, but the text is not valid JSON: trailing commas, comments, single quotes, unquoted keys, or truncation. (Message wording aside, decoding already succeeded — this is strictly a syntax failure.)","triggerScenarios":"Config contains JS-style JSON (comments, trailing commas, unquoted keys), is truncated mid-object, or has smart quotes from a word processor.","commonSituations":"JSON5/JSONC-style configs pasted from tutorials; secrets-injection template placeholders breaking string quoting; partial writes after crash.","solutions":["Validate: jq . mcporter.json (or python -m json.tool) and fix the reported line/col","Remove comments and trailing commas; double-quote all keys and string values","If truncated, restore from VCS or regenerate the file"],"exampleFix":"// before\n {\n   // my servers\n   \"mcpServers\": { \"fetch\": { \"command\": \"npx\", } },\n }\n// after\n {\n   \"mcpServers\": { \"fetch\": { \"command\": \"npx\" } }\n }","handlingStrategy":"validation","validationCode":"import json\n\ndef config_json_valid(path) -> bool:\n    try:\n        json.load(open(path, encoding=\"utf-8\"))\n        return True\n    except (ValueError, OSError, UnicodeError):\n        return False","typeGuard":null,"tryCatchPattern":"except McporterConfigError as exc:\n    if isinstance(exc.__cause__, json.JSONDecodeError):\n        show(f\"syntax error at line {exc.__cause__.lineno} col {exc.__cause__.colno}\")","preventionTips":["JSON only: no comments, no trailing commas, double quotes everywhere","Lint with `python -m json.tool file` or jq in CI","Never hand-edit while tired; use a JSON-aware editor"],"tags":["mcporter","mcp","json","config"],"backgroundTag":null,"analyzedSha":"93ae1d18c37b707dec053c7c4f9d91cd8ef8943d","analyzedAt":"2026-08-14T22:54:06.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}