Skip to content

fix(agent): critical UnboundLocalError on Agent() without max_budget#1643

Closed
MervinPraison wants to merge 1 commit into
mainfrom
fix/agent-executionconfig-scope
Closed

fix(agent): critical UnboundLocalError on Agent() without max_budget#1643
MervinPraison wants to merge 1 commit into
mainfrom
fix/agent-executionconfig-scope

Conversation

@MervinPraison
Copy link
Copy Markdown
Owner

@MervinPraison MervinPraison commented May 9, 2026

Critical Regression Fix

Root cause: PR #1635 introduced a local from ..config.feature_configs import ExecutionConfig inside Agent.__init__ at line 743, inside the if max_budget is not None: branch.

Per Python scoping rules, a name assigned anywhere in a function is treated as local throughout the entire function. When max_budget is None (the common case), the local branch never executes but line 777 still references ExecutionConfig and raises:

UnboundLocalError: cannot access local variable 'ExecutionConfig' where it is not associated with a value

This broke every single Agent() instantiation without max_budget โ€” effectively the entire library for most users.

Fix

ExecutionConfig is already imported at module level (line 162-166). Only resolve_execution needs the lazy local import. Removed the redundant ExecutionConfig from the local import statement and added a comment explaining why it must stay at module-level.

Validation

  • Agent(name='test', instructions='Be helpful') โ€” now works โœ…
  • Agent(name='test', max_budget=1.0) โ€” still works โœ…
  • 311 agent unit tests pass โœ…
  • Test tests/unit/agent/test_scientific_writer_agent.py::TestScientificWriterAgentIntegration::test_real_agentic_test surfaced this bug

Discovery

Found while doing thorough post-merge validation of PRs #1635, #1637, #1626, #1639, #1611, #1600 against AGENTS.md standards.

Summary by CodeRabbit

  • Refactor
    • Improved internal code organization within the agent initialization process to enhance stability and maintainability.

Note: This release contains internal optimizations with no user-facing changes.

Review Change Stack

PR #1635 introduced a local 'from ... import ExecutionConfig' inside
__init__ (line 743 inside 'if max_budget is not None:' branch).
Per Python scoping rules, a name assigned anywhere in a function is
treated as local throughout the entire function. When max_budget is
None (the common case), the local branch never executes but line 777
still hits 'ExecutionConfig' and raises UnboundLocalError, breaking
every Agent() instantiation without max_budget.

ExecutionConfig is already imported at module level (line 162-166).
Only resolve_execution needs the local lazy import.

Test: tests/unit/agent/test_scientific_writer_agent.py surfaced this;
now passes along with 311 other agent unit tests.
Copilot AI review requested due to automatic review settings May 9, 2026 21:50
@qodo-code-review
Copy link
Copy Markdown

โ“˜ You've reached your Qodo monthly free-tier limit. Reviews pause until next month โ€” upgrade your plan to continue now, or link your paid account if you already have one.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 9, 2026

Caution

Review failed

The pull request is closed.

โ„น๏ธ Recent review info
โš™๏ธ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3c52ec2d-486d-4a4c-b795-8851c03cc6d5

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between 78f0a71 and d755392.

๐Ÿ“’ Files selected for processing (1)
  • src/praisonai-agents/praisonaiagents/agent/agent.py

๐Ÿ“ Walkthrough

Walkthrough

Agent.init's max_budget convenience handling adjusts local imports to prevent UnboundLocalError. The code now imports only resolve_execution locally instead of ExecutionConfig, allowing the module-level ExecutionConfig reference to be used in the budget merge logic.

Changes

ExecutionConfig Import Scope Fix

Layer / File(s) Summary
Import Scope and UnboundLocalError Fix
src/praisonai-agents/praisonaiagents/agent/agent.py
The max_budget block removes local ExecutionConfig import and imports only resolve_execution, with comments explaining the UnboundLocalError avoidance behavior caused by local imports within __init__.

Estimated code review effort

๐ŸŽฏ 2 (Simple) | โฑ๏ธ ~8 minutes

Possibly related issues

Possibly related PRs

  • MervinPraison/PraisonAI#1372: Both PRs modify Agent.init to fix local-scope issues (import/unbound-local handling for max_budget vs. variable shadowing).
  • MervinPraison/PraisonAI#1635: Both PRs modify Agent.init's max_budget wiring; this PR fixes the local import/UnboundLocalError by importing only resolve_execution, while the retrieved PR added the max_budget parameter and merge logic.

Poem

๐Ÿฐ A scope to fix within the init hall,
No more UnboundLocal errors to appall!
Just resolve_execution, sleek and small,
Module-level config conquers all! โœจ

โœจ Finishing Touches
๐Ÿ“ Generate docstrings
  • Create stacked PR
  • Commit on current branch
๐Ÿงช Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/agent-executionconfig-scope
โš”๏ธ Resolve merge conflicts
  • Resolve merge conflict in branch fix/agent-executionconfig-scope

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

โค๏ธ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@MervinPraison
Copy link
Copy Markdown
Owner Author

@copilot Do a thorough review of this PR. Read ALL existing reviewer comments above from Qodo, Coderabbit, and Gemini first โ€” incorporate their findings.

Review areas:

  1. Bloat check: Are changes minimal and focused? Any unnecessary code or scope creep?
  2. Security: Any hardcoded secrets, unsafe eval/exec, missing input validation?
  3. Performance: Any module-level heavy imports? Hot-path regressions?
  4. Tests: Are tests included? Do they cover the changes adequately?
  5. Backward compat: Any public API changes without deprecation?
  6. Code quality: DRY violations, naming conventions, error handling?
  7. Address reviewer feedback: If Qodo, Coderabbit, or Gemini flagged valid issues, include them in your review
  8. Suggest specific improvements with code examples where possible

@MervinPraison
Copy link
Copy Markdown
Owner Author

Closing โ€” PR #1635 was reverted via #1642, so the ExecutionConfig scoping bug this PR was fixing no longer exists on main. Verified Agent(name='test', instructions='Be helpful') works correctly post-revert.

@MervinPraison MervinPraison deleted the fix/agent-executionconfig-scope branch May 9, 2026 21:51
Copilot stopped work on behalf of MervinPraison due to an error May 9, 2026 21:51
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses an UnboundLocalError in the Agent class by removing a redundant local import of ExecutionConfig within the init method. Feedback suggests also moving the local import of resolve_execution to the module level to prevent potential scope issues and ensure consistency with the fix applied to ExecutionConfig.

# make Python treat ExecutionConfig as a local name throughout this
# entire __init__ function and break the branch below that uses it
# when max_budget is None (UnboundLocalError).
from ..config.feature_configs import resolve_execution
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The local import of resolve_execution is redundant and carries the same risk of UnboundLocalError that this PR is fixing for ExecutionConfig. If resolve_execution were ever used outside this if block later in the __init__ function, it would trigger another UnboundLocalError when max_budget is None because Python treats names assigned via imports as local to the entire function scope.

Since ExecutionConfig is already imported at the module level (lines 162-166) from the same ..config.feature_configs module, the module is already loaded. There is no performance benefit to lazy-loading resolve_execution here. It is recommended to move resolve_execution to the module-level imports for safety and consistency.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 9, 2026

Greptile Summary

This PR fixes a Python scoping bug introduced by PR #1635: adding a from ..config.feature_configs import ExecutionConfig, resolve_execution inside a conditional branch caused Python to treat ExecutionConfig as a local variable throughout the entire __init__ function, raising UnboundLocalError on every Agent() call that didn't pass max_budget.

  • Root cause fixed: ExecutionConfig removed from the local import so only resolve_execution is lazy-loaded; ExecutionConfig continues to be resolved from the existing module-level import at line 162.
  • Scope of impact: Every Agent() instantiation without max_budget (the default case for most users) was broken; this single-line change restores that path.

Confidence Score: 5/5

Safe to merge โ€” the change is a minimal, well-targeted one-line fix that restores the pre-regression behavior for all standard Agent() calls.

The change removes exactly one symbol (ExecutionConfig) from a misplaced local import. The module-level import at lines 162-166 already covers it, so both the max_budget and non-max_budget code paths are now correct. The fix is consistent with the rest of the codebase and the PR description accurately describes the Python scoping rule at play.

No files require special attention. The single changed file has a straightforward, isolated fix.

Important Files Changed

Filename Overview
src/praisonai-agents/praisonaiagents/agent/agent.py Removes ExecutionConfig from the lazy local import inside the if max_budget is not None: branch, fixing an UnboundLocalError that affected every Agent() call without max_budget. ExecutionConfig is already imported at module level (lines 162-166) so the module-level reference at line 782 now resolves correctly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Agent.__init__(max_budget=...)"] --> B{max_budget is not None?}
    B -- "Yes (budget provided)" --> C["lazy import: resolve_execution only\n(ExecutionConfig from module level)"]
    C --> D{execution is None?}
    D -- Yes --> E["execution = ExecutionConfig(max_budget=max_budget)"]
    D -- No --> F["resolve_execution(execution)\nthen merge max_budget"]
    F --> G[line 782: apply_config_defaults uses module-level ExecutionConfig โœ…]
    E --> G
    B -- "No (common case)" --> H["skip branch entirely"]
    H --> G

    style G fill:#d4edda,stroke:#28a745
    style C fill:#fff3cd,stroke:#ffc107
Loading

Reviews (1): Last reviewed commit: "fix(agent): critical UnboundLocalError o..." | Re-trigger Greptile

@MervinPraison
Copy link
Copy Markdown
Owner Author

@claude You are the FINAL architecture reviewer. If the branch is under MervinPraison/PraisonAI (not a fork), you are able to make modifications to this branch and push directly. SCOPE: Focus ONLY on Python packages (praisonaiagents, praisonai). Do NOT modify praisonai-rust or praisonai-ts. Read ALL comments above from Gemini, Qodo, CodeRabbit, and Copilot carefully before responding.

Phase 1: Review per AGENTS.md

  1. Protocol-driven: check heavy implementations vs core SDK
  2. Backward compatible: ensure zero feature regressions
  3. Performance: no hot-path regressions

Phase 2: FIX Valid Issues
4. For any VALID bugs or architectural flaws found by Gemini, CodeRabbit, Qodo, Copilot, or any other reviewer: implement the fix
5. Push all code fixes directly to THIS branch (do NOT create a new PR)
6. Comment a summary of exact files modified and what you skipped

Phase 3: Final Verdict
7. If all issues are resolved, approve the PR / close the Issue
8. If blocking issues remain, request changes / leave clear action items

@praisonai-triage-agent
Copy link
Copy Markdown
Contributor

praisonai-triage-agent Bot commented May 9, 2026

Claude finished @MervinPraison's task โ€”โ€” View job


Final Architecture Review - PR #1643 โœ… ANALYSIS COMPLETE

Task: Conduct final architecture review per AGENTS.md guidelines and implement fixes for valid issues found by previous reviewers.

Todo Checklist:


๐ŸŽฏ Final Verdict: PR IS OBSOLETE - CLOSE WITHOUT MERGING

Key Finding: The original issue NO LONGER EXISTS

โœ… Verified: PR #1635 was completely reverted via #1642
โœ… Tested: Agent(name='test', instructions='Be helpful') works correctly on main branch
โœ… Confirmed: No max_budget parameter exists in current Agent.init

Architecture Review per AGENTS.md

Phase 1: Architecture Compliance โœ…

  • Protocol-driven: โœ… Core SDK changes were minimal and appropriate
  • Backward Compatible: โœ… No breaking changes to public API
  • Performance: โœ… No hot-path or import-time regressions

Phase 2: Reviewer Analysis

Reviewer Finding Status
Gemini Move resolve_execution import to module level for consistency โš ๏ธ VALID but moot
CodeRabbit Good fix, clear explanation โœ… Accurate
Greptile Safe minimal fix โœ… Accurate
Copilot Should do thorough review โœ… Done
Qodo Hit free tier limit โ„น๏ธ N/A

Gemini's concern: The local import of resolve_execution carries theoretical UnboundLocalError risk if used outside the conditional block. This is architecturally sound advice.

Phase 3: Implementation Decision

โŒ NO FIXES IMPLEMENTED - Reason: The entire PR addresses a problem that no longer exists post-revert of #1635.

Technical Summary

Original Problem (PR #1635):

# BROKEN: Local import inside conditional
if max_budget is not None:
    from ..config.feature_configs import ExecutionConfig, resolve_execution
    # ... uses ExecutionConfig later outside this block = UnboundLocalError

Current State (main branch):

  • No max_budget parameter exists in Agent.init
  • No conditional imports that could cause scoping issues
  • All ExecutionConfig usage goes through consolidated execution=ExecutionConfig(...) pattern per AGENTS.md ยง5.3

Recommendation:

CLOSE PR #1643 - The regression it fixes was already resolved by reverting the problematic PR #1635 via #1642.


@MervinPraison MervinPraison review requested due to automatic review settings May 9, 2026 22:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant