{"record":{"id":"618de1eb4a6c06d5","repo":"Panniantong/Agent-Reach","slug":"mcporter","errorCode":null,"errorMessage":"mcporter 配置文件无法安全读取","messagePattern":"mcporter 配置文件无法安全读取","errorType":"exception","errorClass":"McporterConfigError","httpStatus":null,"severity":"error","filePath":"agent_reach/channels/mcporter.py","lineNumber":121,"sourceCode":"\n    project_path = root / \"config\" / \"mcporter.json\"\n    if os.path.lexists(project_path):\n        layers.append((project_path, \"project\"))\n    return layers\n\n\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:","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/Panniantong/Agent-Reach/blob/93ae1d18c37b707dec053c7c4f9d91cd8ef8943d/agent_reach/channels/mcporter.py#L103-L139","documentation":"Raised when reading a mcporter config layer raises OSError (EPERM, EACCES, EIO...) or UnicodeError (file not decodable as UTF-8) — i.e. the file exists and passes the symlink/regular-file policy, but the OS read or UTF-8 decode fails. Pure I/O and encoding problems, as opposed to error 10's policy refusals or error 12's missing file.","triggerScenarios":"File exists but permission denied (chmod 000, different owner); I/O error reading from a failing disk or network mount; file saved in GBK/Latin-1 with non-ASCII bytes so payload.decode('utf-8') raises UnicodeDecodeError.","commonSituations":"Configs edited on Windows in a legacy codepage; restrictive umask or root-owned file from a sudo-run tool; flaky NFS/FUSE mounts.","solutions":["Re-save the file as UTF-8 (no BOM needed, JSON must be UTF-8 anyway)","Fix ownership/permissions: chown $USER file && chmod 644 file","If on a network mount, retry from a stable path or copy the file locally","Confirm with: file mcporter.json (should say UTF-8/ASCII text)"],"exampleFix":"# before: file encoded in GBK with Chinese comments\n# after\n iconv -f GBK -t UTF-8 mcporter.json > mcporter.json.utf8 && mv mcporter.json.utf8 mcporter.json","handlingStrategy":"try-catch","validationCode":"import os\n\ndef config_readable_utf8(path) -> bool:\n    try:\n        with open(path, \"rb\") as fh:\n            data = fh.read(1024 * 1024)\n        data.decode(\"utf-8\")\n        return True\n    except (OSError, UnicodeError):\n        return False","typeGuard":null,"tryCatchPattern":"except McporterConfigError as exc:\n    if isinstance(exc.__cause__, UnicodeError):\n        hint = \"re-save the config as UTF-8\"\n    elif isinstance(exc.__cause__, OSError):\n        hint = f\"fix permissions on the config: {exc.__cause__}\"","preventionTips":["Always save JSON configs as UTF-8","chmod 644 configs owned by the running user","Don't serve configs from flaky network mounts during doctor runs"],"tags":["mcporter","mcp","encoding","filesystem","permissions"],"backgroundTag":null,"analyzedSha":"93ae1d18c37b707dec053c7c4f9d91cd8ef8943d","analyzedAt":"2026-08-14T22:54:06.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}