Skip to content

fix(config): resolve dead code and dictionary shallow update issues i…#5934

Open
2bright wants to merge 3 commits into
crewAIInc:mainfrom
2bright:main
Open

fix(config): resolve dead code and dictionary shallow update issues i…#5934
2bright wants to merge 3 commits into
crewAIInc:mainfrom
2bright:main

Conversation

@2bright
Copy link
Copy Markdown

@2bright 2bright commented May 26, 2026

…n process_config

  • Remove the incorrect 'continue' statement that caused unreachable code for dict updates.
  • Implement a recursive dict_deep_update helper to support deep merging of nested YAML configurations.
  • Adjust update order to ensure user-explicit arguments properly override default configurations.

Summary by CodeRabbit

  • Bug Fixes
    • Configuration handling now deep-merges nested dictionary settings so partial updates no longer overwrite unrelated values.
    • Unknown configuration fields are ignored to prevent invalid entries from taking effect.
    • Previously applied settings are preserved unless explicitly overridden, and config values are copied to prevent unintended side effects.

Review Change Stack

…n process_config

- Remove the incorrect 'continue' statement that caused unreachable code for dict updates.
- Implement a recursive `dict_deep_update` helper to support deep merging of nested YAML configurations.
- Adjust update order to ensure user-explicit arguments properly override default configurations.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 26, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 98ff57cb-cb11-46e6-8e4a-8e2aa3850cd0

📥 Commits

Reviewing files that changed from the base of the PR and between cc734b0 and ee351ef.

📒 Files selected for processing (1)
  • lib/crewai/src/crewai/utilities/config.py

📝 Walkthrough

Walkthrough

process_config now deep-merges nested dictionaries when applying config values, deep-copies dict/list values, skips unknown model fields, preserves existing non-dict overrides, and uses a new recursive _dict_deep_update helper for in-place nested dict updates.

Changes

Configuration Deep Merge

Layer / File(s) Summary
Config deep merge implementation
lib/crewai/src/crewai/utilities/config.py
Adds copy import, introduces _dict_deep_update recursive helper, and reworks the config application loop to deep-copy container values, skip unknown model fields, preserve existing overrides unless both sides are dicts, and deep-merge dictionaries with override precedence.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through keys and nested stacks,
Merging leaves along my tracks,
Copies kept safe, overrides win the fight,
Now configs nest and merge just right.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: fixing dead code and shallow dictionary update issues in the process_config function.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
lib/crewai/src/crewai/utilities/config.py (2)

22-27: ⚡ Quick win

Fix indentation to use 4 spaces per level.

The function body uses 2-space indentation increment instead of Python's conventional 4 spaces. This is inconsistent with the rest of the file (lines 18-19, 31-43) and violates PEP 8.

📐 Proposed fix for indentation
     def dict_deep_update(to_dict: dict[str, Any], from_dict: dict[str, Any]) -> None:
-      """Internal helper to recursively update to_dict with from_dict values in-place."""
-      for key, value in from_dict.items():
-        if key in to_dict and isinstance(to_dict[key], dict) and isinstance(value, dict):
-          dict_deep_update(to_dict[key], value)
-        else:
-          to_dict[key] = value
+        """Internal helper to recursively update to_dict with from_dict values in-place."""
+        for key, value in from_dict.items():
+            if key in to_dict and isinstance(to_dict[key], dict) and isinstance(value, dict):
+                dict_deep_update(to_dict[key], value)
+            else:
+                to_dict[key] = value
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/src/crewai/utilities/config.py` around lines 22 - 27, The function
dict_deep_update has its body indented with 2 spaces; update the indentation to
use 4 spaces per level throughout the function (the for loop, the nested if
isinstance(...) and its recursive call dict_deep_update(to_dict[key], value),
and the else branch assigning to_dict[key] = value) so it matches the rest of
the file and PEP8 style.

34-38: ⚡ Quick win

Consider deep copying override values to prevent aliasing bugs.

When both the override and config values are dictionaries, the current implementation deep copies the config value but not the override value before merging. This means values[key] will contain references to mutable objects from override_value, potentially causing aliasing bugs if the same override dict is passed to multiple model instances or modified elsewhere.

For consistency with how config values are handled (line 36, 40) and to prevent unexpected shared mutable state, consider deep copying the override value before merging.

🔒 Proposed fix to deep copy override values
         if (override_value := values.get(key)) is not None:
             if isinstance(override_value, dict) and isinstance(value, dict):
                 config_value = copy.deepcopy(value)
-                dict_deep_update(config_value, override_value)
+                dict_deep_update(config_value, copy.deepcopy(override_value))
                 values[key] = config_value

Alternatively, if you want to deep copy override values consistently for dicts and lists:

         if (override_value := values.get(key)) is not None:
             if isinstance(override_value, dict) and isinstance(value, dict):
                 config_value = copy.deepcopy(value)
-                dict_deep_update(config_value, override_value)
+                override_copy = copy.deepcopy(override_value) if isinstance(override_value, (dict, list)) else override_value
+                dict_deep_update(config_value, override_copy)
                 values[key] = config_value
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/src/crewai/utilities/config.py` around lines 34 - 38, The merge
currently deep-copies the original config (config_value = copy.deepcopy(value))
but passes override_value directly into dict_deep_update, leaving shared
references; change the merge to deep-copy the override before merging (e.g.,
create override_copy = copy.deepcopy(override_value) and call
dict_deep_update(config_value, override_copy)) so values[key] contains no
references to the original override dict; reference symbols: values, key,
override_value, config_value, dict_deep_update.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@lib/crewai/src/crewai/utilities/config.py`:
- Around line 22-27: The function dict_deep_update has its body indented with 2
spaces; update the indentation to use 4 spaces per level throughout the function
(the for loop, the nested if isinstance(...) and its recursive call
dict_deep_update(to_dict[key], value), and the else branch assigning
to_dict[key] = value) so it matches the rest of the file and PEP8 style.
- Around line 34-38: The merge currently deep-copies the original config
(config_value = copy.deepcopy(value)) but passes override_value directly into
dict_deep_update, leaving shared references; change the merge to deep-copy the
override before merging (e.g., create override_copy =
copy.deepcopy(override_value) and call dict_deep_update(config_value,
override_copy)) so values[key] contains no references to the original override
dict; reference symbols: values, key, override_value, config_value,
dict_deep_update.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: b97d7154-db5a-4ebc-a054-f5f313572dcb

📥 Commits

Reviewing files that changed from the base of the PR and between bad64b1 and 0f02a3d.

📒 Files selected for processing (1)
  • lib/crewai/src/crewai/utilities/config.py

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
lib/crewai/src/crewai/utilities/config.py (1)

38-44: 💤 Low value

Consider using a well-established library for deep merging.

While the custom implementation is correct and straightforward, libraries like mergedeep or similar provide battle-tested deep merge functionality with additional features (merge strategies, handling edge cases). This could reduce maintenance burden.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/crewai/src/crewai/utilities/config.py` around lines 38 - 44, The custom
recursive updater _dict_deep_update should be replaced with a battle-tested
deep-merge library to reduce maintenance; add a dependency such as mergedeep (or
deepmerge), import its merge function, and replace calls to
_dict_deep_update(to_dict, from_dict) with the library call that performs an
in‑place merge (e.g., mergedeep.merge(to_dict, from_dict) or
deepmerge.algo.merge(to_dict, from_dict) depending on chosen lib) to preserve
the original in-place behavior; remove the custom _dict_deep_update
implementation, update the module imports, and run/adjust any tests to ensure
identical merge semantics (dict overwrites and nested dict merging) are
maintained.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/crewai/src/crewai/utilities/config.py`:
- Around line 38-44: The _dict_deep_update function body is indented with 2
spaces; reformat to use 4-space indentation per PEP 8, updating the docstring
line, the for key, value loop, the if/else block and the recursive
call/assignment lines so each block level uses 4 spaces (preserve existing
logic/function names exactly: _dict_deep_update, to_dict, from_dict).

---

Nitpick comments:
In `@lib/crewai/src/crewai/utilities/config.py`:
- Around line 38-44: The custom recursive updater _dict_deep_update should be
replaced with a battle-tested deep-merge library to reduce maintenance; add a
dependency such as mergedeep (or deepmerge), import its merge function, and
replace calls to _dict_deep_update(to_dict, from_dict) with the library call
that performs an in‑place merge (e.g., mergedeep.merge(to_dict, from_dict) or
deepmerge.algo.merge(to_dict, from_dict) depending on chosen lib) to preserve
the original in-place behavior; remove the custom _dict_deep_update
implementation, update the module imports, and run/adjust any tests to ensure
identical merge semantics (dict overwrites and nested dict merging) are
maintained.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 48a2a771-9e3c-44e1-ac20-2e6305effd35

📥 Commits

Reviewing files that changed from the base of the PR and between 0f02a3d and cc734b0.

📒 Files selected for processing (1)
  • lib/crewai/src/crewai/utilities/config.py

Comment thread lib/crewai/src/crewai/utilities/config.py Outdated
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