Skip to content

fix: OpenTelemetry logs and traces showing proper crew names#5564

Closed
renatonitta wants to merge 13 commits intomainfrom
rn/con-109-fix-crew-name-in-traces
Closed

fix: OpenTelemetry logs and traces showing proper crew names#5564
renatonitta wants to merge 13 commits intomainfrom
rn/con-109-fix-crew-name-in-traces

Conversation

@renatonitta
Copy link
Copy Markdown
Contributor

@renatonitta renatonitta commented Apr 20, 2026

Summary

This PR fixes OpenTelemetry logs and traces showing crew_name: "crew" for every unnamed automation, making it impossible to tell which automation ran. Root cause: Crew.name defaulted to the literal string "crew", which propagated to every downstream event.

The default is now None, resolved at construction time via a model_validator that falls back to the class name, matching Flow's existing pattern.

Changes

  • Crew.name defaults to None instead of the literal "crew".
  • _resolve_name model validator (mode="after") fills in the class name when no explicit name is provided.
  • @crew decorator propagates the @CrewBase class name to the returned Crew instance, preserving any explicit Crew(name=...) set inside the factory method.

Behavior

Construction Before After
Crew(name="My Automation", ...) crew My Automation
class MyCrew(Crew)MyCrew(...) crew MyCrew
@CrewBase class ResearchCrew: @crew def crew(self): crew ResearchCrew
Crew(...) (bare, no name) crew Crew

Note

Medium Risk
Changes Crew.name defaulting and propagation logic, which affects event payloads, memory scoping namespaces, and OpenTelemetry trace metadata for all crews. Risk is moderate due to behavior changes in identifiers that may impact downstream logging/metrics expectations.

Overview
Unnamed Crew instances no longer default to the literal string "crew"; Crew.name now defaults to None and is resolved post-init to the concrete class name via a new _resolve_name model validator while tracking whether the user explicitly set name.

Telemetry and UI surfaces now use this resolved name: kickoff/training/testing events emit the resolved crew_name, checkpoint resume panels cast crew.name as non-null, and the tracing listener treats missing/empty crew names as "Unknown Crew" instead of accepting falsy values.

The @crew factory decorator now propagates the @CrewBase class name onto the returned Crew instance only when name was not explicitly provided, and tests were updated/added to lock in these naming semantics (plus a small uv.lock timestamp change).

Reviewed by Cursor Bugbot for commit 6a41e6f. Bugbot is set up for automated code reviews on this repo. Configure here.

@linear
Copy link
Copy Markdown

linear Bot commented Apr 20, 2026

@renatonitta renatonitta self-assigned this Apr 20, 2026
Comment thread lib/crewai/tests/test_project.py Fixed
Comment thread lib/crewai/src/crewai/crew.py
Comment thread lib/crewai/tests/test_project.py Fixed
Comment thread lib/crewai/tests/test_project.py Fixed
Comment thread lib/crewai/tests/test_project.py Fixed
@renatonitta renatonitta requested a review from vinibrsl April 20, 2026 22:41
Comment thread lib/crewai/src/crewai/crew.py Outdated
return self

@property
def display_name(self) -> str:
Copy link
Copy Markdown
Contributor

@greysonlalonde greysonlalonde Apr 20, 2026

Choose a reason for hiding this comment

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

Rather than adding new property logic, can we stick this in a @model_validator to keep from adding new attrs? Something like:

@model_validator(mode="after")                                                                                                                       
def _resolve_name(self) -> Self:                                                                                                                     
    if self.name is None:                                                                                                                            
        self.name = type(self).__name__
    return self  

Then we can keep the same .name accessor throughout files.

The decorator would need to unconditionally assign the name like so:

crew_instance.name = getattr(self, "_crew_name", None) or crew_instance.name

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

Comment thread lib/crewai/src/crewai/project/annotations.py Outdated
Comment thread lib/crewai/src/crewai/project/annotations.py
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 6a41e6f. Configure here.

# pollutes `model_fields_set`.
self._name_was_explicit = "name" in self.model_fields_set
if not self._name_was_explicit:
self.name = type(self).__name__
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Validator doesn't fallback when name is explicitly None

Low Severity

The _resolve_name validator uses "name" in self.model_fields_set to decide whether to apply the class-name fallback. When a user explicitly passes Crew(name=None), Pydantic includes "name" in model_fields_set, so _name_was_explicit becomes True and the fallback is skipped—leaving name as None. This breaks the "guaranteed non-None" invariant that downstream cast(str, self.name) calls rely on. The fallback condition needs to check self.name is None rather than not self._name_was_explicit, while keeping _name_was_explicit based on model_fields_set for the decorator's separate concern.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 6a41e6f. Configure here.

@renatonitta
Copy link
Copy Markdown
Contributor Author

Closing this in favor of #5574

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.

2 participants