affaan-m/ECC · error · ConfigError
Config file not found: {path}
Error message
Config file not found: {path} What it means
`load_config` catches `FileNotFoundError` from `open(path)` and re-raises it as a domain `ConfigError(f"Config file not found: {path}")` using exception chaining (`from e`). This is the 'specific exception handling' pattern — the alternative `except:` bare clause that returns `None` is shown as the anti-pattern.
Source
Thrown at skills/python-patterns/SKILL.md:151
"""Render the object to a string."""
def render_all(items: list[Renderable]) -> str:
"""Render all items that implement the Renderable protocol."""
return "\n".join(item.render() for item in items)
```
## Error Handling Patterns
### Specific Exception Handling
```python
# Good: Catch specific exceptions
def load_config(path: str) -> Config:
try:
with open(path) as f:
return Config.from_json(f.read())
except FileNotFoundError as e:
raise ConfigError(f"Config file not found: {path}") from e
except json.JSONDecodeError as e:
raise ConfigError(f"Invalid JSON in config: {path}") from e
# Bad: Bare except
def load_config(path: str) -> Config:
try:
with open(path) as f:
return Config.from_json(f.read())
except:
return None # Silent failure!
```
### Exception Chaining
```python
def process_data(data: str) -> Result:
try:
parsed = json.loads(data)View on GitHub (pinned to 01e15490f0)
Solutions
- Verify the path with `pathlib.Path(path).resolve()` and `is_file()` before calling, and log the resolved absolute path.
- Confirm the working directory the process runs from (containers often start in `/app`, not the repo root).
- For deployments, ensure the config file is mounted/copied into the image at the expected absolute path.
- Make the path required and absolute in production; fall back to a packaged default only for dev.
Example fix
# before
try:
with open(path) as f:
return Config.from_json(f.read())
except FileNotFoundError as e:
raise ConfigError(f"Config file not found: {path}") from e
# after — resolve+validate before open, clearer message
from pathlib import Path
p = Path(path).expanduser().resolve()
if not p.is_file():
raise ConfigError(f"Config file not found: {p} (cwd={Path.cwd()})")
with p.open() as f:
return Config.from_json(f.read()) Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def config_exists(path: str) -> bool:
return Path(path).expanduser().is_file() Type guard
null
Try / catch
try:
cfg = load_config(path)
except ConfigError as e:
if 'not found' in str(e):
fall_back_to_packaged_default()
raise Prevention
- Resolve and validate the path with `pathlib` before `open`.
- Use absolute paths in production; ship a packaged default for dev.
- Log the resolved absolute path and current working directory in the error.
When it happens
Trigger: Caller passes a path that does not exist on disk: wrong working directory, typo, missing config in deployment, env var pointing at `/etc/app/config.json` that was not mounted.
Common situations: Working directory differs between dev and container so the relative path resolves wrong. Helm/k8s forgot to mount the ConfigMap. CI runs from repo root but the app expects `./config/`. Path built from an env var that was unset, yielding `None` or `''`.
Related errors
- X API error {resp.status_code}: {resp.text}
- Invalid ECC repo root: unreadable package.json at ${packageJ
- The canonical ito-compute-cli is unpublished and ECC will no
- Invalid mode "${mode}". Allowed modes: ${allowedModes.join('
- request failed
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/1acfd73e8c9b5f76.
Report an issue: GitHub.