BUG-HUNT: [boundary] Potential IndexError in _collect_adr_inventory #2381

Open
opened 2026-04-03 17:26:56 +00:00 by freemo · 1 comment
Owner

Background and Context

The function _collect_adr_inventory in hooks/adr_hooks.py processes the status_history field from ADR front-matter during the MkDocs build. At line 415, the code accesses status_history[-1][1] without first validating that the last entry contains at least two elements. A malformed status_history entry (e.g., a list with only a date and no status string) will raise an unhandled IndexError, crashing the entire MkDocs build process.

This is a boundary category bug: the code does not guard against malformed input that violates the assumed structure.

Current Behavior

Given a front-matter like:

status_history:
  - [2026-01-01, "draft"]
  - [2026-02-01]  # Missing status string

The line:

last_status = str(status_history[-1][1]).strip()

raises IndexError: list index out of range, halting the MkDocs build.

Expected Behavior

The code should validate that each status_history entry has the expected number of elements before indexing. If an entry is malformed, it should log a warning and either skip the ADR or fall back to a default status value — without crashing the build.

Acceptance Criteria

  • _collect_adr_inventory validates that status_history[-1] has at least 2 elements before accessing index [1]
  • A log.warning(...) is emitted when a malformed entry is detected, identifying the affected ADR file
  • A default/fallback value (e.g., "unknown") is used when the entry is malformed, so the build continues
  • No IndexError is raised for any malformed status_history input
  • Existing valid ADR processing behaviour is unchanged

Supporting Information

  • File: hooks/adr_hooks.py
  • Function: _collect_adr_inventory
  • Line: 415
  • Suggested Fix:
last_entry = status_history[-1]
if len(last_entry) > 1:
    last_status = str(last_entry[1]).strip()
else:
    last_status = "unknown"
    log.warning("Malformed status_history entry in %s: %s", f.src_path, last_entry)

Metadata

  • Branch: fix/adr-hooks-status-history-index-error
  • Commit Message: fix(docs): guard against IndexError in _collect_adr_inventory for malformed status_history
  • Milestone: v3.6.0
  • Parent Epic: #400

Subtasks

  • Add length guard before accessing status_history[-1][1] in _collect_adr_inventory
  • Emit log.warning(...) with file path and malformed entry when guard triggers
  • Use "unknown" (or equivalent sentinel) as fallback last_status value
  • Tests (Behave): Add scenario — malformed status_history entry does not raise IndexError
  • Tests (Behave): Add scenario — valid status_history entry continues to parse correctly
  • Verify coverage >=97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • All subtasks above are completed and checked off.
  • 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: Bug Hunting | Agent: ca-new-issue-creator

## Background and Context The function `_collect_adr_inventory` in `hooks/adr_hooks.py` processes the `status_history` field from ADR front-matter during the MkDocs build. At line 415, the code accesses `status_history[-1][1]` without first validating that the last entry contains at least two elements. A malformed `status_history` entry (e.g., a list with only a date and no status string) will raise an unhandled `IndexError`, crashing the entire MkDocs build process. This is a **boundary** category bug: the code does not guard against malformed input that violates the assumed structure. ## Current Behavior Given a front-matter like: ```yaml status_history: - [2026-01-01, "draft"] - [2026-02-01] # Missing status string ``` The line: ```python last_status = str(status_history[-1][1]).strip() ``` raises `IndexError: list index out of range`, halting the MkDocs build. ## Expected Behavior The code should validate that each `status_history` entry has the expected number of elements before indexing. If an entry is malformed, it should log a warning and either skip the ADR or fall back to a default status value — without crashing the build. ## Acceptance Criteria - [ ] `_collect_adr_inventory` validates that `status_history[-1]` has at least 2 elements before accessing index `[1]` - [ ] A `log.warning(...)` is emitted when a malformed entry is detected, identifying the affected ADR file - [ ] A default/fallback value (e.g., `"unknown"`) is used when the entry is malformed, so the build continues - [ ] No `IndexError` is raised for any malformed `status_history` input - [ ] Existing valid ADR processing behaviour is unchanged ## Supporting Information - **File**: `hooks/adr_hooks.py` - **Function**: `_collect_adr_inventory` - **Line**: 415 - **Suggested Fix**: ```python last_entry = status_history[-1] if len(last_entry) > 1: last_status = str(last_entry[1]).strip() else: last_status = "unknown" log.warning("Malformed status_history entry in %s: %s", f.src_path, last_entry) ``` --- ## Metadata - **Branch**: `fix/adr-hooks-status-history-index-error` - **Commit Message**: `fix(docs): guard against IndexError in _collect_adr_inventory for malformed status_history` - **Milestone**: v3.6.0 - **Parent Epic**: #400 ## Subtasks - [ ] Add length guard before accessing `status_history[-1][1]` in `_collect_adr_inventory` - [ ] Emit `log.warning(...)` with file path and malformed entry when guard triggers - [ ] Use `"unknown"` (or equivalent sentinel) as fallback `last_status` value - [ ] Tests (Behave): Add scenario — malformed `status_history` entry does not raise `IndexError` - [ ] Tests (Behave): Add scenario — valid `status_history` entry continues to parse correctly - [ ] Verify coverage >=97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - All subtasks above are completed and checked off. - 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: Bug Hunting | Agent: ca-new-issue-creator
freemo added this to the v3.6.0 milestone 2026-04-03 17:27:01 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Medium — Potential IndexError in _collect_adr_inventory when processing malformed status_history entries. This is a boundary condition bug.
  • Milestone: v3.6.0
  • MoSCoW: Could Have — This only triggers with malformed ADR front-matter, which is unlikely in normal operation. Defensive coding improvement.
  • Parent Epic: #362 (Security & Safety Hardening)

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

Issue triaged by project owner: - **State**: Verified - **Priority**: Medium — Potential `IndexError` in `_collect_adr_inventory` when processing malformed `status_history` entries. This is a boundary condition bug. - **Milestone**: v3.6.0 - **MoSCoW**: Could Have — This only triggers with malformed ADR front-matter, which is unlikely in normal operation. Defensive coding improvement. - **Parent Epic**: #362 (Security & Safety Hardening) --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
freemo removed this from the v3.6.0 milestone 2026-04-07 01:00:10 +00:00
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.

Blocks
#400 Epic: Post-MVP Security
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#2381
No description provided.