Panniantong/Agent-Reach · error · ConfigReadOnlyError
当前配置是只读的,不能修改
Error message
当前配置是只读的,不能修改
What it means
Raised by Config.set() (agent_reach/config.py:173) when the Config instance was created with read_only=True. Read-only mode exists so callers (e.g. concurrent sessions or sandboxed/agent contexts) can inspect config without risking writes; any mutation via set() is rejected before the in-memory dict is touched. The Chinese message '当前配置是只读的,不能修改' means 'the current config is read-only and cannot be modified'.
Source
Thrown at agent_reach/config.py:173
raise ConfigReadOnlyError("当前配置是只读的,不能保存")
self._ensure_dir()
_atomic_write_yaml(self.config_path, self.data)
def get(self, key: str, default: Any = None) -> Any:
"""Get a config value. Also checks environment variables (uppercase)."""
# Config file first
if key in self.data:
return self.data[key]
# Then env var (uppercase)
env_val = os.environ.get(key.upper())
if env_val:
return env_val
return default
def set(self, key: str, value: Any):
"""Set a config value and save."""
if self.read_only:
raise ConfigReadOnlyError("当前配置是只读的,不能修改")
missing = object()
previous = self.data.get(key, missing)
self.data[key] = value
try:
self.save()
except BaseException:
if previous is missing:
self.data.pop(key, None)
else:
self.data[key] = previous
raise
def delete(self, key: str):
"""Delete a config key and save."""
if self.read_only:
raise ConfigReadOnlyError("当前配置是只读的,不能修改")
missing = object()
previous = self.data.pop(key, missing)View on GitHub (pinned to 93ae1d18c3)
Solutions
- Create or obtain a writable Config instance (read_only defaults to False) before calling set()
- Check cfg.read_only before attempting writes and surface a clear message to the user
- If the write must persist, route it through the CLI (`agent-reach configure <key>`) instead of mutating a read-only handle
- Catch agent_reach.config.ConfigReadOnlyError and fail fast instead of silently skipping the save
Example fix
# before
from agent_reach.config import Config
cfg = Config(read_only=True)
cfg.set('twitter_cookies', raw) # raises ConfigReadOnlyError
# after
cfg = Config() # writable instance
cfg.set('twitter_cookies', raw) Defensive patterns
Strategy: type-guard
Validate before calling
if cfg.read_only:
raise PermissionError('config handle is read-only; open a writable Config()') Type guard
def is_writable_config(cfg) -> bool:
return not getattr(cfg, 'read_only', False) Try / catch
from agent_reach.config import ConfigReadOnlyError
try:
cfg.set(key, value)
except ConfigReadOnlyError:
# open a writable instance instead of mutating the shared handle
writable = Config(); writable.set(key, value) Prevention
- Pass read_only=True only to consumers that never write
- Centralize writes in one helper that checks cfg.read_only first
- Prefer the CLI `agent-reach configure` for user-driven changes
When it happens
Trigger: Calling cfg.set('key', value) on a Config constructed with Config(..., read_only=True) — typically instances obtained from a read-only accessor or explicitly instantiated with that flag.
Common situations: An agent or script grabbed a shared read-only Config handle and then tried to store credentials; refactoring code that previously used a writable instance; tests that build Config with read_only=True for safety but later need to write.
Related errors
- 当前配置是只读的,不能保存
- gh hosts.yml 无法安全读取
- gh hosts.yml 不是有效的 UTF-8 YAML
- gh hosts.yml 顶层必须是对象
- gh hosts.yml 的 github.com 配置无效
AI-assisted analysis of Panniantong/Agent-Reach@93ae1d18c3 (2026-08-14).
Data as JSON: /api/errors/62a7c4ffbe7cdc78.
Report an issue: GitHub.