{"record":{"id":"b0ff657c45f81dd1","repo":"Panniantong/Agent-Reach","slug":"gh-hosts-yml-users","errorCode":null,"errorMessage":"gh hosts.yml 的 users 配置无效","messagePattern":"gh hosts\\.yml 的 users 配置无效","errorType":"exception","errorClass":"GitHubConfigError","httpStatus":null,"severity":"error","filePath":"agent_reach/channels/github.py","lineNumber":80,"sourceCode":"        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:\n    if any(os.environ.get(name) for name in (\"GH_TOKEN\", \"GITHUB_TOKEN\")):\n        return True\n    if config is None:\n        return False\n    try:\n        return bool(config.get(\"github_token\"))\n    except Exception as exc:\n        raise GitHubConfigError(\"Agent Reach 的 GitHub 配置无法读取\") from exc\n\n\nclass GitHubChannel(Channel):\n    name = \"github\"\n    description = \"GitHub 仓库和代码\"\n    backends = [\"gh CLI\"]","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/Panniantong/Agent-Reach/blob/93ae1d18c37b707dec053c7c4f9d91cd8ef8943d/agent_reach/channels/github.py#L62-L98","documentation":"Raised when the github.com host entry's 'users' key exists but is not a mapping. gh writes 'users:' as a map of login names to metadata; a list or scalar there is treated as corrupt configuration.","triggerScenarios":"hosts.yml github.com block contains 'users: []' (empty list), 'users: someuser', or 'users:\\n- a'. users is not None and not a dict → error. Absent 'users' key or a proper dict is fine.","commonSituations":"Hand-crafted hosts.yml following an outdated gh format; older gh versions or forks writing a different users shape; YAML shortcut ('users: [alice]') from copy-paste.","solutions":["Remove the 'users' key entirely if you only use oauth_token/user (it is optional for this check)","Rewrite users as a mapping: 'users:\\n  alice: {}'","Regenerate with `gh auth login` to get gh's current canonical format"],"exampleFix":"# before\n github.com:\n   oauth_token: gho_x\n   users: [alice]\n# after\n github.com:\n   oauth_token: gho_x\n   user: alice","handlingStrategy":"validation","validationCode":"import yaml\n\ndef users_entry_valid(path) -> bool:\n    try:\n        d = yaml.safe_load(open(path, encoding=\"utf-8\").read()) or {}\n        host = d.get(\"github.com\") or {}\n    except Exception:\n        return False\n    users = host.get(\"users\")\n    return users is None or isinstance(users, dict)","typeGuard":null,"tryCatchPattern":"except GitHubConfigError as exc:\n    log(f\"gh users block malformed: {exc}\")\n    treat_github_as_unconfigured()","preventionTips":["Omit the users key unless gh itself wrote it","Keep gh's canonical structure; let gh own the file","Check `gh auth status` output matches expectations after manual edits"],"tags":["github","gh-cli","yaml","config"],"backgroundTag":null,"analyzedSha":"93ae1d18c37b707dec053c7c4f9d91cd8ef8943d","analyzedAt":"2026-08-14T22:54:06.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}