Skip to content

fix(step): use 'is not None' guard to preserve falsy return values in @step decorator#2940

Open
devteamaegis wants to merge 2 commits into
Chainlit:mainfrom
devteamaegis:fix/step-decorator-falsy-output
Open

fix(step): use 'is not None' guard to preserve falsy return values in @step decorator#2940
devteamaegis wants to merge 2 commits into
Chainlit:mainfrom
devteamaegis:fix/step-decorator-falsy-output

Conversation

@devteamaegis
Copy link
Copy Markdown

@devteamaegis devteamaegis commented May 29, 2026

Summary

Two fixes in the messaging layer:

1. step.py — falsy-output silently dropped (primary bug)

The @step decorator records the decorated function's return value via:

# Before
if result and not step.output:
    step.output = result

A plain truthiness guard (if result) silently drops any falsy-but-meaningful return value: 0, False, "", [], {}, etc.

Example:

@cl.step
async def count_errors(text: str) -> int:
    # returns 0 when text is clean — this output was NEVER persisted
    return len(find_errors(text))

The 0 return is falsy, so step.output is never set. The step appears to have no output in the UI, and the value is not persisted.

Fix: Use result is not None — only skip recording when the function explicitly returns nothing.

# After
if result is not None and not step.output:
    step.output = result

This applies to both the async_wrapper and sync_wrapper paths.

2. message.py@classmethod names first parameter self

MessageBase.from_dict is decorated with @classmethod but its first parameter is named self instead of the conventional cls. While Python itself doesn't care about the parameter name, type-checkers (mypy, pyright) and linters flag this as an error, and it misleads readers into thinking self is an instance.

Renamed to cls following PEP 8 / Python convention.


Summary by cubic

Fixes the @step decorator to keep falsy but valid return values (e.g., 0, False, "", [], {}). Ensures step outputs are saved and shown; also aligns a classmethod signature with conventions to satisfy linters.

  • Bug Fixes
    • backend/chainlit/step.py: use result is not None in both async and sync wrappers so falsy outputs are recorded.
    • backend/chainlit/message.py: rename self to cls in from_dict to follow classmethod convention and pass type-checkers.

Written for commit 98d81cb. Summary will update on new commits.

Review in cubic

@dosubot dosubot Bot added size:XS This PR changes 0-9 lines, ignoring generated files. backend Pertains to the Python backend. bug Something isn't working labels May 29, 2026
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

No issues found across 2 files

Re-trigger cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Pertains to the Python backend. bug Something isn't working size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant