BUG-HUNT: [error-handling] retry_service_overrides JSON string never validated at Settings initialization #7321

Open
opened 2026-04-10 16:47:48 +00:00 by HAL9000 · 3 comments
Owner

Bug Report: Error Handling — Deferred JSON Parse Failure for retry_service_overrides

Severity Assessment

  • Impact: Malformed JSON in CLEVERAGENTS_RETRY_SERVICE_OVERRIDES silently passes Settings validation. The error only surfaces when a service attempts to parse the overrides at runtime, potentially crashing mid-operation or during the first retry attempt of a critical service call.
  • Likelihood: Low — requires misconfigured environment; but when it occurs the failure mode is cryptic and distant from the root cause
  • Priority: Low

Location

  • File: src/cleveragents/config/settings.py
  • Function/Class: Settings (class field retry_service_overrides)
  • Lines: 636–644

Description

The retry_service_overrides field stores a JSON string that is never parsed or validated during Settings initialization. The field is defined as:

retry_service_overrides: str = Field(
    default="{}",
    max_length=10000,
    validation_alias=AliasChoices("CLEVERAGENTS_RETRY_SERVICE_OVERRIDES"),
    description=(
        "JSON string mapping service names to retry policy overrides. "
        'Example: \'{"plan_service": {"retry": {"max_attempts": 5}}}\''
    ),
)

This is a str field, so Pydantic will accept any string up to 10000 chars — including {"broken": invalid_json}. The model_validator only validates that retry_max_delay >= retry_base_delay (lines 647–654), not that the JSON field is parseable.

If a user sets CLEVERAGENTS_RETRY_SERVICE_OVERRIDES='{"malformed":' the application will start successfully, but any code path that calls json.loads(settings.retry_service_overrides) will receive a json.JSONDecodeError at an arbitrary point during execution.

Evidence

# src/cleveragents/config/settings.py lines 636-644
retry_service_overrides: str = Field(
    default="{}",
    max_length=10000,
    validation_alias=AliasChoices("CLEVERAGENTS_RETRY_SERVICE_OVERRIDES"),
    description=(
        "JSON string mapping service names to retry policy overrides. "
        'Example: \'{"plan_service": {"retry": {"max_attempts": 5}}}\''
    ),
)
# ← No JSON validation anywhere in model_validator or model_post_init

The model validator at lines 647–654 only checks:

@model_validator(mode="after")
def _max_delay_ge_base_delay(self) -> Settings:
    if self.retry_max_delay < self.retry_base_delay:
        raise ValueError(...)
    return self

No JSON parse validation for retry_service_overrides.

Expected Behavior

Invalid JSON in retry_service_overrides should raise a ValueError at Settings construction time, not silently pass and fail later.

Actual Behavior

Invalid JSON is accepted at startup; json.JSONDecodeError is raised later when the field is consumed.

Suggested Fix

Add JSON validation in the model_validator:

@model_validator(mode="after")
def _max_delay_ge_base_delay(self) -> Settings:
    if self.retry_max_delay < self.retry_base_delay:
        raise ValueError(...)
    # Validate retry_service_overrides is valid JSON
    try:
        import json
        json.loads(self.retry_service_overrides)
    except json.JSONDecodeError as exc:
        raise ValueError(
            f"retry_service_overrides is not valid JSON: {exc}"
        ) from exc
    return self

Category

error-handling

TDD Note

After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: @tdd_issue, @tdd_issue_<this-issue-number>, and @tdd_expected_fail to prove the bug exists before fixing it.


Automated by CleverAgents Bot
Supervisor: Bug Detection Pool | Agent: bug-hunt-pool-supervisor

## Bug Report: Error Handling — Deferred JSON Parse Failure for retry_service_overrides ### Severity Assessment - **Impact**: Malformed JSON in `CLEVERAGENTS_RETRY_SERVICE_OVERRIDES` silently passes Settings validation. The error only surfaces when a service attempts to parse the overrides at runtime, potentially crashing mid-operation or during the first retry attempt of a critical service call. - **Likelihood**: Low — requires misconfigured environment; but when it occurs the failure mode is cryptic and distant from the root cause - **Priority**: Low ### Location - **File**: `src/cleveragents/config/settings.py` - **Function/Class**: `Settings` (class field `retry_service_overrides`) - **Lines**: 636–644 ### Description The `retry_service_overrides` field stores a JSON string that is never parsed or validated during `Settings` initialization. The field is defined as: ```python retry_service_overrides: str = Field( default="{}", max_length=10000, validation_alias=AliasChoices("CLEVERAGENTS_RETRY_SERVICE_OVERRIDES"), description=( "JSON string mapping service names to retry policy overrides. " 'Example: \'{"plan_service": {"retry": {"max_attempts": 5}}}\'' ), ) ``` This is a `str` field, so Pydantic will accept any string up to 10000 chars — including `{"broken": invalid_json}`. The `model_validator` only validates that `retry_max_delay >= retry_base_delay` (lines 647–654), not that the JSON field is parseable. If a user sets `CLEVERAGENTS_RETRY_SERVICE_OVERRIDES='{"malformed":'` the application will start successfully, but any code path that calls `json.loads(settings.retry_service_overrides)` will receive a `json.JSONDecodeError` at an arbitrary point during execution. ### Evidence ```python # src/cleveragents/config/settings.py lines 636-644 retry_service_overrides: str = Field( default="{}", max_length=10000, validation_alias=AliasChoices("CLEVERAGENTS_RETRY_SERVICE_OVERRIDES"), description=( "JSON string mapping service names to retry policy overrides. " 'Example: \'{"plan_service": {"retry": {"max_attempts": 5}}}\'' ), ) # ← No JSON validation anywhere in model_validator or model_post_init ``` The model validator at lines 647–654 only checks: ```python @model_validator(mode="after") def _max_delay_ge_base_delay(self) -> Settings: if self.retry_max_delay < self.retry_base_delay: raise ValueError(...) return self ``` No JSON parse validation for `retry_service_overrides`. ### Expected Behavior Invalid JSON in `retry_service_overrides` should raise a `ValueError` at Settings construction time, not silently pass and fail later. ### Actual Behavior Invalid JSON is accepted at startup; `json.JSONDecodeError` is raised later when the field is consumed. ### Suggested Fix Add JSON validation in the `model_validator`: ```python @model_validator(mode="after") def _max_delay_ge_base_delay(self) -> Settings: if self.retry_max_delay < self.retry_base_delay: raise ValueError(...) # Validate retry_service_overrides is valid JSON try: import json json.loads(self.retry_service_overrides) except json.JSONDecodeError as exc: raise ValueError( f"retry_service_overrides is not valid JSON: {exc}" ) from exc return self ``` ### Category error-handling ### TDD Note After this bug issue is verified, a corresponding Type/Testing issue will be created for TDD. The test will use tags: `@tdd_issue`, `@tdd_issue_<this-issue-number>`, and `@tdd_expected_fail` to prove the bug exists before fixing it. --- **Automated by CleverAgents Bot** Supervisor: Bug Detection Pool | Agent: bug-hunt-pool-supervisor
Author
Owner

Verified — Bug: retry_service_overrides JSON never validated at initialization. MoSCoW: Should-have. Priority: Medium.


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

✅ **Verified** — Bug: retry_service_overrides JSON never validated at initialization. MoSCoW: Should-have. Priority: Medium. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Author
Owner

Verified — Bug: retry_service_overrides JSON never validated at initialization. MoSCoW: Should-have. Priority: Medium.


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

✅ **Verified** — Bug: retry_service_overrides JSON never validated at initialization. MoSCoW: Should-have. Priority: Medium. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
Author
Owner

Verified — Bug: retry_service_overrides JSON never validated at initialization. MoSCoW: Should-have. Priority: Medium.


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

✅ **Verified** — Bug: retry_service_overrides JSON never validated at initialization. MoSCoW: Should-have. Priority: Medium. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: project-owner-pool-supervisor
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#7321
No description provided.