{"record":{"id":"8427fe818c7ccb0d","repo":"Panniantong/Agent-Reach","slug":"gh-hosts-yml-utf-8-yaml","errorCode":null,"errorMessage":"gh hosts.yml 不是有效的 UTF-8 YAML","messagePattern":"gh hosts\\.yml 不是有效的 UTF-8 YAML","errorType":"exception","errorClass":"GitHubConfigError","httpStatus":null,"severity":"error","filePath":"agent_reach/channels/github.py","lineNumber":66,"sourceCode":"    return Path.home() / \".config\" / \"gh\" / \"hosts.yml\"\n\n\ndef _saved_github_host_configured() -> bool:\n    \"\"\"Inspect github.com's hosts.yml entry without executing gh.\"\"\"\n    hosts_path = _gh_hosts_path()\n    try:\n        raw = read_small_text_no_follow(\n            hosts_path,\n            max_bytes=_MAX_HOSTS_BYTES,\n        )\n    except (OSError, PrivatePathError, UnicodeError) as exc:\n        raise GitHubConfigError(\"gh hosts.yml 无法安全读取\") from exc\n    if raw is None:\n        return False\n    try:\n        payload = yaml.safe_load(raw)\n    except yaml.YAMLError as exc:\n        raise GitHubConfigError(\"gh hosts.yml 不是有效的 UTF-8 YAML\") from exc\n    if payload is None:\n        return False\n    if not isinstance(payload, dict):\n        raise GitHubConfigError(\"gh hosts.yml 顶层必须是对象\")\n\n    host = payload.get(\"github.com\")\n    if host is None:\n        return False\n    if not isinstance(host, dict):\n        raise GitHubConfigError(\"gh hosts.yml 的 github.com 配置无效\")\n\n    users = host.get(\"users\")\n    if users is not None and not isinstance(users, dict):\n        raise GitHubConfigError(\"gh hosts.yml 的 users 配置无效\")\n    return bool(host.get(\"oauth_token\") or host.get(\"user\") or users)\n\n\ndef _explicit_github_credentials(config) -> bool:","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/Panniantong/Agent-Reach/blob/93ae1d18c37b707dec053c7c4f9d91cd8ef8943d/agent_reach/channels/github.py#L48-L84","documentation":"Raised when yaml.safe_load() on the already-read hosts.yml content throws yaml.YAMLError. The file was read and UTF-8-decoded successfully, but the text is not parseable YAML (bad indentation, stray tabs, unclosed quotes/brackets).","triggerScenarios":"Calling the GitHub credential probe with a hosts.yml whose text is malformed YAML: tabs used for indentation, a truncated file, hand-edited structure errors, or an empty scalar where a mapping is expected mid-document.","commonSituations":"Manual editing of hosts.yml to add a second account; a partially-written file after a crash or concurrent `gh auth login`; copy-paste from a browser introducing smart quotes; secret-injection tooling mangling the file.","solutions":["Validate the file: python -c \"import yaml,sys; yaml.safe_load(open(sys.argv[1]))\" ~/.config/gh/hosts.yml","Fix indentation (spaces only, 2 per level) and quoting; typical shape is 'github.com:\\n  oauth_token: ...\\n  user: ...'","Regenerate the file with `gh auth login` if hand-repair fails","Keep the file under _MAX_HOSTS_BYTES and free of non-UTF-8 bytes (save as UTF-8)"],"exampleFix":"# before (invalid: tab indentation)\n github.com:\n\toauth_token: gho_xxx\n# after\n github.com:\n   oauth_token: gho_xxx\n   user: you","handlingStrategy":"validation","validationCode":"import yaml\n\ndef hosts_yaml_ok(path) -> bool:\n    try:\n        with open(path, \"r\", encoding=\"utf-8\") as fh:\n            return isinstance(yaml.safe_load(fh), (dict, type(None)))\n    except (OSError, UnicodeError, yaml.YAMLError):\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    _saved_github_host_configured()\nexcept GitHubConfigError as exc:\n    log_warning(f\"gh config unreadable: {exc}; run `gh auth login`\")","preventionTips":["Use spaces (never tabs) when editing hosts.yml","Validate YAML with yaml.safe_load before running doctor","Regenerate via gh auth login after any manual edit mistake"],"tags":["github","gh-cli","yaml","config"],"backgroundTag":null,"analyzedSha":"93ae1d18c37b707dec053c7c4f9d91cd8ef8943d","analyzedAt":"2026-08-14T22:54:06.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}