BUG-HUNT: [error-handling] Unhandled FileNotFoundError in ActorConfigSchema.from_yaml_file #1931

Open
opened 2026-04-03 00:16:18 +00:00 by freemo · 2 comments
Owner

Metadata

  • Branch: fix/error-handling-actor-schema-from-yaml-file
  • Commit Message: fix(actor): handle FileNotFoundError and IOError in ActorConfigSchema.from_yaml_file
  • Milestone: v3.7.0
  • Parent Epic: ⚠️ No parent Epic provided — requires manual linking by a maintainer.

Background and Context

ActorConfigSchema.from_yaml_file in src/cleveragents/actor/schema.py raises a raw FileNotFoundError when the specified YAML file does not exist (line ~880). While the actor CLI's _load_config helper in cli/commands/actor.py guards against missing files via typer.BadParameter for the --config path, ActorConfigSchema.from_yaml_file is a public API method that can be called directly by other code paths (e.g., programmatic usage, future CLI commands, or test harnesses). In those contexts, the FileNotFoundError propagates unhandled as a raw Python exception with a bare traceback rather than a user-friendly error.

This is consistent with the pattern already fixed for ActionConfigSchema.from_yaml_file (issue #1682) and follows the project's fail-fast and argument-validation principles from CONTRIBUTING.md.

Current Behavior

When ActorConfigSchema.from_yaml_file("nonexistent.yaml") is called with a path that does not exist, a raw FileNotFoundError is raised and propagates to the caller without being wrapped in a user-friendly error type. Callers that do not explicitly catch FileNotFoundError will receive an unhandled exception with a bare traceback.

Expected Behavior

ActorConfigSchema.from_yaml_file should:

  1. Raise FileNotFoundError for missing files (current behavior is acceptable at the domain layer — the issue is that IOError and UnicodeDecodeError from the subsequent path.open() / read() call are not caught).
  2. Catch IOError (which covers OSError, PermissionError, and FileNotFoundError from the OS-level file read) and UnicodeDecodeError from the path.open(encoding="utf-8") call, and re-raise them as ValueError with a user-friendly message that includes the file path and original exception detail — consistent with the fix applied in #1682 for ActionConfigSchema.

Acceptance Criteria

  • ActorConfigSchema.from_yaml_file wraps IOError and UnicodeDecodeError from the file-read operation in a ValueError with a descriptive message including the file path.
  • The raised ValueError message contains the file path and the original exception detail.
  • No bare except or generic Exception catch is introduced — only IOError and UnicodeDecodeError are caught.
  • All existing tests continue to pass.
  • New Behave BDD scenarios cover the IOError and UnicodeDecodeError paths.
  • Coverage remains ≥ 97%.

Supporting Information

  • Related fix: #1682 (ActionConfigSchema.from_yaml_file — same pattern, already fixed)
  • Affected file: src/cleveragents/actor/schema.py, method ActorConfigSchema.from_yaml_file (~line 858)
  • CONTRIBUTING.md: "Only catch exceptions when you can meaningfully handle them"; "Fail fast when preconditions aren't met"

Subtasks

  • Wrap the path.open(encoding="utf-8") / read call in ActorConfigSchema.from_yaml_file (src/cleveragents/actor/schema.py) in a try...except block
  • Catch IOError (covers OSError, FileNotFoundError, PermissionError) and UnicodeDecodeError specifically
  • Re-raise as ValueError with a user-friendly error message that includes the file path and original exception detail
  • Tests (Behave): Add scenario for IOError when file cannot be read (e.g. missing file, permission denied)
  • Tests (Behave): Add scenario for UnicodeDecodeError when file contains non-UTF-8 bytes
  • Tests (Behave): Verify the raised ValueError message contains the file path
  • Run nox -e typecheck — confirm no Pyright errors introduced
  • Run nox -e coverage_report — confirm coverage remains ≥ 97%
  • Run nox (all default sessions) — confirm all stages pass

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • ActorConfigSchema.from_yaml_file catches IOError and UnicodeDecodeError and raises ValueError with a user-friendly message.
  • No bare except or generic Exception catch introduced — only specific exception types are caught.
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation.
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly.
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done.
  • All nox stages pass.
  • Coverage >= 97%.

Automated by CleverAgents Bot
Supervisor: Unknown | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/error-handling-actor-schema-from-yaml-file` - **Commit Message**: `fix(actor): handle FileNotFoundError and IOError in ActorConfigSchema.from_yaml_file` - **Milestone**: v3.7.0 - **Parent Epic**: ⚠️ *No parent Epic provided — requires manual linking by a maintainer.* ## Background and Context `ActorConfigSchema.from_yaml_file` in `src/cleveragents/actor/schema.py` raises a raw `FileNotFoundError` when the specified YAML file does not exist (line ~880). While the actor CLI's `_load_config` helper in `cli/commands/actor.py` guards against missing files via `typer.BadParameter` for the `--config` path, `ActorConfigSchema.from_yaml_file` is a public API method that can be called directly by other code paths (e.g., programmatic usage, future CLI commands, or test harnesses). In those contexts, the `FileNotFoundError` propagates unhandled as a raw Python exception with a bare traceback rather than a user-friendly error. This is consistent with the pattern already fixed for `ActionConfigSchema.from_yaml_file` (issue #1682) and follows the project's fail-fast and argument-validation principles from CONTRIBUTING.md. ## Current Behavior When `ActorConfigSchema.from_yaml_file("nonexistent.yaml")` is called with a path that does not exist, a raw `FileNotFoundError` is raised and propagates to the caller without being wrapped in a user-friendly error type. Callers that do not explicitly catch `FileNotFoundError` will receive an unhandled exception with a bare traceback. ## Expected Behavior `ActorConfigSchema.from_yaml_file` should: 1. Raise `FileNotFoundError` for missing files (current behavior is acceptable at the domain layer — the issue is that `IOError` and `UnicodeDecodeError` from the subsequent `path.open()` / `read()` call are **not** caught). 2. Catch `IOError` (which covers `OSError`, `PermissionError`, and `FileNotFoundError` from the OS-level file read) and `UnicodeDecodeError` from the `path.open(encoding="utf-8")` call, and re-raise them as `ValueError` with a user-friendly message that includes the file path and original exception detail — consistent with the fix applied in #1682 for `ActionConfigSchema`. ## Acceptance Criteria - [ ] `ActorConfigSchema.from_yaml_file` wraps `IOError` and `UnicodeDecodeError` from the file-read operation in a `ValueError` with a descriptive message including the file path. - [ ] The raised `ValueError` message contains the file path and the original exception detail. - [ ] No bare `except` or generic `Exception` catch is introduced — only `IOError` and `UnicodeDecodeError` are caught. - [ ] All existing tests continue to pass. - [ ] New Behave BDD scenarios cover the `IOError` and `UnicodeDecodeError` paths. - [ ] Coverage remains ≥ 97%. ## Supporting Information - Related fix: #1682 (`ActionConfigSchema.from_yaml_file` — same pattern, already fixed) - Affected file: `src/cleveragents/actor/schema.py`, method `ActorConfigSchema.from_yaml_file` (~line 858) - CONTRIBUTING.md: "Only catch exceptions when you can meaningfully handle them"; "Fail fast when preconditions aren't met" ## Subtasks - [ ] Wrap the `path.open(encoding="utf-8")` / `read` call in `ActorConfigSchema.from_yaml_file` (`src/cleveragents/actor/schema.py`) in a `try...except` block - [ ] Catch `IOError` (covers `OSError`, `FileNotFoundError`, `PermissionError`) and `UnicodeDecodeError` specifically - [ ] Re-raise as `ValueError` with a user-friendly error message that includes the file path and original exception detail - [ ] Tests (Behave): Add scenario for `IOError` when file cannot be read (e.g. missing file, permission denied) - [ ] Tests (Behave): Add scenario for `UnicodeDecodeError` when file contains non-UTF-8 bytes - [ ] Tests (Behave): Verify the raised `ValueError` message contains the file path - [ ] Run `nox -e typecheck` — confirm no Pyright errors introduced - [ ] Run `nox -e coverage_report` — confirm coverage remains ≥ 97% - [ ] Run `nox` (all default sessions) — confirm all stages pass ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - `ActorConfigSchema.from_yaml_file` catches `IOError` and `UnicodeDecodeError` and raises `ValueError` with a user-friendly message. - No bare `except` or generic `Exception` catch introduced — only specific exception types are caught. - A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation. - The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly. - The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done. - All nox stages pass. - Coverage >= 97%. --- **Automated by CleverAgents Bot** Supervisor: Unknown | Agent: ca-new-issue-creator
freemo added this to the v3.7.0 milestone 2026-04-03 00:17:53 +00:00
Author
Owner

⚠️ Orphan Issue — Requires Manual Parent Linking

This issue has no parent Epic to link to. No open Type/Epic issue exists for BUG-HUNT error-handling work (the only open Epic is #1678, which is scoped to CI Execution Time Optimization).

A maintainer should either:

  1. Create a BUG-HUNT error-handling Epic and link this issue as a child (this issue blocks the parent Epic), or
  2. Link this issue to an existing appropriate parent Epic.

Per CONTRIBUTING.md: "All non-Epic, non-Legendary issues should be linked to at least one parent when one exists."


Automated by CleverAgents Bot
Supervisor: Unknown | Agent: ca-new-issue-creator

⚠️ **Orphan Issue — Requires Manual Parent Linking** This issue has no parent Epic to link to. No open `Type/Epic` issue exists for BUG-HUNT error-handling work (the only open Epic is #1678, which is scoped to CI Execution Time Optimization). A maintainer should either: 1. Create a BUG-HUNT error-handling Epic and link this issue as a child (this issue **blocks** the parent Epic), or 2. Link this issue to an existing appropriate parent Epic. Per CONTRIBUTING.md: *"All non-Epic, non-Legendary issues should be linked to at least one parent when one exists."* --- **Automated by CleverAgents Bot** Supervisor: Unknown | Agent: ca-new-issue-creator
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • MoSCoW: MoSCoW/Should Have — bug or error handling improvement.

Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified - **MoSCoW**: MoSCoW/Should Have — bug or error handling improvement. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cleveragents/cleveragents-core#1931
No description provided.