Skip to content

fix(describe): guard pr_description config reads against missing keys (#2238)#2478

Merged
naorpeled merged 1 commit into
mainfrom
fix/pr-description-config-attribute-error
Jun 26, 2026
Merged

fix(describe): guard pr_description config reads against missing keys (#2238)#2478
naorpeled merged 1 commit into
mainfrom
fix/pr-description-config-attribute-error

Conversation

@naorpeled

Copy link
Copy Markdown
Member

What

Fixes the 'DynaBox' object has no attribute 'enable_large_pr_handling' crash on /describe.

Closes #2238

Why it still happens after #2234

#2234 restored enable_large_pr_handling / max_ai_calls / async_ai_calls as defaults in configuration.toml, but the reads were left as direct attribute access. The catch is custom_merge_loader replaces a whole section instead of merging fields (it documents this in its own docstring). So any user whose custom .pr_agent.toml has a [pr_description] section that omits these keys loses the defaults at runtime, and the unguarded read throws. retry_with_fallback_models swallows it as a failed prediction and keeps trying models until the run fails - which is exactly what a v0.34 user with an older config reported.

The fix

Read the three keys via .get(..., default) at the call sites, so the documented defaults apply even when a custom config replaces the section:

  • pr_agent/tools/pr_description.py:211 - enable_large_pr_handling (default True)
  • pr_agent/tools/pr_description.py:247 - async_ai_calls (default True)
  • pr_agent/algo/pr_processing.py:262 - max_ai_calls (default 4)

Defaults match configuration.toml.

Test

Added test_pr_description_reads_fall_back_when_keys_missing, which reproduces the overridden section with a DynaBox missing the keys, asserts bare attribute access raises the original error, and verifies the guarded reads fall back to the defaults.

A custom .pr_agent.toml that overrides the [pr_description] section drops the
section defaults, because custom_merge_loader replaces sections instead of
merging fields. The unguarded reads of enable_large_pr_handling, async_ai_calls
and max_ai_calls then raised 'DynaBox object has no attribute ...', which
retry_with_fallback_models swallowed as a failed prediction until every model
failed and /describe crashed.

Read these keys via .get(..., default) so the documented defaults apply when a
custom config omits them. #2238
@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Fix /describe crash when pr_description config keys are missing
🐞 Bug fix 🧪 Tests 🕐 10-20 Minutes

Grey Divider

Description

• Prevent /describe from crashing when custom .pr_agent.toml omits pr_description defaults.
• Use guarded Dynaconf reads with explicit defaults for large-PR handling and AI call limits.
• Add regression test covering missing-key behavior on DynaBox config sections.
Diagram

graph TD
  user(("User")) --> describe["/describe"] --> cfg[("Dynaconf settings")] --> prdesc["pr_description.py"] --> prproc["pr_processing.py"] --> llm{{"LLM models"}}
  toml[["Custom .pr_agent.toml"]] --> cfg

  subgraph Legend
    direction LR
    _actor(("Actor")) ~~~ _api["API/Command"] ~~~ _cfg[("Config")] ~~~ _mod["Module"] ~~~ _ext{{"External"}} ~~~ _file[["Config file"]]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Deep-merge config sections in custom_merge_loader
  • ➕ Fixes this class of missing-default bugs across all sections, not just pr_description
  • ➕ Keeps call sites simple (attribute access remains safe)
  • ➖ Higher blast radius: changes config semantics for existing users
  • ➖ Requires careful precedence/merge rules and additional tests across settings layout
2. Centralize defaults via schema/validation step on settings load
  • ➕ Single place to enforce required keys and defaults
  • ➕ Can emit clearer diagnostics when keys are missing/mistyped
  • ➖ More implementation overhead than a targeted fix
  • ➖ Still requires decisions about how to handle partially overridden sections

Recommendation: The PR’s targeted .get(..., default) reads are the best immediate fix: low risk, aligns with documented defaults, and directly prevents /describe crashes for partially overridden [pr_description] sections. Consider a follow-up to address section replacement behavior more broadly (deep-merge or validation) if similar issues appear elsewhere.

Files changed (3) +23 / -3

Bug fix (2) +3 / -3
pr_processing.pyDefault-safe read for pr_description.max_ai_calls +1/-1

Default-safe read for pr_description.max_ai_calls

• Replaces direct attribute access to 'pr_description.max_ai_calls' with 'get("max_ai_calls", 4)' when computing the number of allowed iterations for large-PR diff generation. Prevents AttributeError when a user overrides the [pr_description] section without this key.

pr_agent/algo/pr_processing.py

pr_description.pyGuard missing pr_description keys for large-PR + async behavior +2/-2

Guard missing pr_description keys for large-PR + async behavior

• Switches 'enable_large_pr_handling' and 'async_ai_calls' reads from attribute access to 'get(..., default)' with defaults matching configuration.toml. This keeps /describe functional when a custom config replaces the section and drops these keys.

pr_agent/tools/pr_description.py

Tests (1) +20 / -0
test_pr_processing_core.pyRegression test for missing-key fallback behavior in DynaBox +20/-0

Regression test for missing-key fallback behavior in DynaBox

• Adds a unit test that reproduces a [pr_description] section missing large-PR keys using 'DynaBox', asserts old-style attribute access raises AttributeError, and verifies '.get(..., default)' returns the expected documented defaults.

tests/unittest/test_pr_processing_core.py

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

  • Author self-review: I have reviewed the code review findings, and addressed the relevant ones.

Qodo Logo

@naorpeled naorpeled merged commit 254ab00 into main Jun 26, 2026
6 checks passed
@naorpeled naorpeled deleted the fix/pr-description-config-attribute-error branch June 26, 2026 21:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

'DynaBox' object has no attribute 'enable_large_pr_handling'

1 participant