crewai - ✅(Solved) Fix [BUG] create_crew() loop variable shadows `provider` function parameter [2 pull requests, 1 comments, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
crewAIInc/crewAI#5270Fetched 2026-04-08 02:51:32
View on GitHub
Comments
1
Participants
1
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×2commented ×1referenced ×1

In create_crew() (cli/create_crew.py), the for-loop on line 214 uses provider as its loop variable:

for provider, env_keys in ENV_VARS.items():

This shadows the provider parameter that's passed in from the CLI (crewai create crew <name> --provider <value>). After the loop finishes, provider no longer holds the user's original selection — it holds whatever the last key from ENV_VARS was (or the key where break was hit).

Currently the parameter isn't read again after the loop (the function uses selected_provider from interactive selection instead), so this doesn't cause a visible behavioral issue today. But it's a latent bug — anyone adding code after the loop that references provider would silently get the wrong value. It also trips static analysis warnings and makes debugging confusing.

Root Cause

In create_crew() (cli/create_crew.py), the for-loop on line 214 uses provider as its loop variable:

for provider, env_keys in ENV_VARS.items():

This shadows the provider parameter that's passed in from the CLI (crewai create crew <name> --provider <value>). After the loop finishes, provider no longer holds the user's original selection — it holds whatever the last key from ENV_VARS was (or the key where break was hit).

Currently the parameter isn't read again after the loop (the function uses selected_provider from interactive selection instead), so this doesn't cause a visible behavioral issue today. But it's a latent bug — anyone adding code after the loop that references provider would silently get the wrong value. It also trips static analysis warnings and makes debugging confusing.

Fix Action

Fixed

PR fix notes

PR #5272: fix: rename loop variable to avoid shadowing provider parameter in create_crew()

Description (problem / solution / changelog)

Summary

Fixes #5270

In create_crew(), the for-loop for provider, env_keys in ENV_VARS.items() was reusing the name provider, which shadows the function parameter passed from the CLI's --provider flag. Renamed the loop variable to env_provider so the original parameter value is preserved.

The parameter isn't currently read after the loop (the function uses selected_provider from interactive selection), so this is a latent bug rather than a visible one today. But shadowing function parameters with loop variables is a classic Python gotcha that makes the code fragile and would trip up anyone trying to use provider later in the function.

Changes

  • Renamed providerenv_provider in the for-loop on line 214 and the assignment on line 219

Test plan

  • All 15 existing tests in test_create_crew.py pass
  • Verified no other references to the loop variable need updating
  • Existing CI should pass (no test changes)

Changed files

  • lib/crewai/src/crewai/cli/create_crew.py (modified, +2/-2)

PR #5274: fix: rename loop variable to avoid shadowing provider parameter in create_crew()

Description (problem / solution / changelog)

Summary

Fixes #5270. In create_crew(), the for loop iterating over ENV_VARS used provider as its loop variable, shadowing the provider function parameter. After the loop, provider held the last key from ENV_VARS (or the key where break was hit) instead of the caller's original value.

Renamed the loop variable from provider to env_provider — a one-line fix (two occurrences).

Added three regression tests covering the ENV_VARS loop with and without matching env vars, and the early-return path when the user declines to override an existing provider.

Review & Testing Checklist for Human

  • Verify the loop at create_crew.py:214 now uses env_provider and correctly assigns existing_provider = env_provider — no other references to the old loop variable remain
  • Note: the bug is currently latent (the provider param isn't read after the loop today), so the new tests exercise the code paths but can't produce a hard failure against the old code. Confirm you're comfortable with that coverage level.

Notes

  • The issue also mentions that the --provider CLI flag doesn't bypass interactive select_provider() — that's a separate issue and not addressed here.

Link to Devin session: https://app.devin.ai/sessions/c91e9f29d3c54447833be29784c7d6ba

<!-- CURSOR_SUMMARY -->

[!NOTE] Low Risk Low risk: a one-line rename to prevent parameter shadowing, plus new mocked CLI tests; minimal behavior change confined to crew creation flow.

Overview Prevents create_crew()’s provider parameter from being accidentally overwritten while iterating ENV_VARS by renaming the loop variable and ensuring existing_provider is set from the correct value.

Adds regression tests covering (1) env var matches with override confirmation, (2) no env var match path, and (3) early return when the user declines to override an existing provider config.

<sup>Reviewed by Cursor Bugbot for commit 1086d5d70d049eabaec3fde6fc01751cd1835105. Bugbot is set up for automated code reviews on this repo. Configure here.</sup>

<!-- /CURSOR_SUMMARY -->

Changed files

  • lib/crewai/src/crewai/cli/create_crew.py (modified, +2/-2)
  • lib/crewai/tests/cli/test_create_crew.py (modified, +131/-0)

Code Example

for provider, env_keys in ENV_VARS.items():

---

def create_crew(
    name: str,
    provider: str | None = None,    # <-- parameter
    skip_provider: bool = False,
    parent_folder: str | None = None,
) -> None:
    ...
    existing_provider = None
    for provider, env_keys in ENV_VARS.items():   # <-- shadows parameter!
        if any(
            "key_name" in details and details["key_name"] in env_vars
            for details in env_keys
        ):
            existing_provider = provider
            break
    # At this point, `provider` is no longer the caller's value
RAW_BUFFERClick to expand / collapse

Description

In create_crew() (cli/create_crew.py), the for-loop on line 214 uses provider as its loop variable:

for provider, env_keys in ENV_VARS.items():

This shadows the provider parameter that's passed in from the CLI (crewai create crew <name> --provider <value>). After the loop finishes, provider no longer holds the user's original selection — it holds whatever the last key from ENV_VARS was (or the key where break was hit).

Currently the parameter isn't read again after the loop (the function uses selected_provider from interactive selection instead), so this doesn't cause a visible behavioral issue today. But it's a latent bug — anyone adding code after the loop that references provider would silently get the wrong value. It also trips static analysis warnings and makes debugging confusing.

Steps to Reproduce

  1. Read create_crew() in lib/crewai/src/crewai/cli/create_crew.py
  2. Notice that line 214 uses provider as the loop variable in for provider, env_keys in ENV_VARS.items()
  3. Add a print(provider) after the loop (line 221) and call create_crew("test", provider="openai")
  4. Observe that provider is no longer "openai"

Expected behavior

The provider parameter should retain its original value throughout the function. Loop variables should not shadow function parameters.

Screenshots/Code snippets

def create_crew(
    name: str,
    provider: str | None = None,    # <-- parameter
    skip_provider: bool = False,
    parent_folder: str | None = None,
) -> None:
    ...
    existing_provider = None
    for provider, env_keys in ENV_VARS.items():   # <-- shadows parameter!
        if any(
            "key_name" in details and details["key_name"] in env_vars
            for details in env_keys
        ):
            existing_provider = provider
            break
    # At this point, `provider` is no longer the caller's value

Operating System

Ubuntu 22.04

Python Version

3.12

crewAI Version

1.13.0

crewAI Tools Version

1.13.0

Virtual Environment

Venv

Evidence

Standard Python scoping behavior — a for loop variable persists after the loop and overwrites any variable with the same name in the enclosing scope. Any linter (pylint W0621, ruff) would flag this as redefined-from-outer-scope.

Possible Solution

Rename the loop variable to env_provider (or similar) so the parameter isn't clobbered. I have a one-line fix ready and will open a PR.

Additional context

Side note: the --provider CLI flag doesn't seem to actually bypass the interactive provider selection — the function always calls select_provider() regardless. That's a separate issue though.

extent analysis

TL;DR

Rename the loop variable in the for loop to avoid shadowing the provider parameter.

Guidance

  • Identify the line of code where the provider parameter is being shadowed (line 214 in create_crew.py) and rename the loop variable to something like env_provider.
  • Verify that the provider parameter retains its original value after the loop by adding a print(provider) statement after the loop.
  • Review the code for any other instances where the provider parameter is used after the loop to ensure it is not being used with the incorrect value.
  • Consider running static analysis tools (like pylint or ruff) to catch similar issues in the future.

Example

for env_provider, env_keys in ENV_VARS.items():
    # ...

Notes

This fix assumes that the only issue is the shadowing of the provider parameter. If there are other issues with the code, additional changes may be necessary.

Recommendation

Apply the workaround by renaming the loop variable to avoid shadowing the provider parameter, as this is a simple and effective fix for the identified issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

The provider parameter should retain its original value throughout the function. Loop variables should not shadow function parameters.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING