Skip to content

Fix #105: don't crash collecting actor tracebacks for finished coroutines#698

Merged
wbarnha merged 1 commit into
masterfrom
claude/fix-105-actor-traceback
Jul 21, 2026
Merged

Fix #105: don't crash collecting actor tracebacks for finished coroutines#698
wbarnha merged 1 commit into
masterfrom
claude/fix-105-actor-traceback

Conversation

@wbarnha

@wbarnha wbarnha commented Jul 19, 2026

Copy link
Copy Markdown
Member

What

Agent.actor_tracebacks() iterated every actor calling actor.traceback(), which delegates to mode's coroutine / async-generator stack formatter. A coroutine or async generator that has finished naturally has no stack frame (cr_frame / ag_frame is None), and mode raises RuntimeError('cannot find stack of coroutine') when asked to format it.

Traceback collection runs inside Consumer.wait_empty around shutdown and rebalances, purely to log agent state. Because the old code built the list in one comprehension, a single finished actor aborted the whole collection — and with it a clean shutdown/rebalance.

Fixes #105.

How

Collect tracebacks one actor at a time and catch RuntimeError per actor, substituting a short placeholder (Could not extract traceback for actor <actor>: <exc>) instead of letting it propagate. This mirrors the workaround several users adopted via a custom Agent subclass, but folds it into faust itself so no subclass is required.

Test

Added test_actor_tracebacks and test_actor_tracebacks__missing_stack in tests/unit/agents/test_agent.py: the first confirms normal collection, the second confirms a RuntimeError('cannot find stack of coroutine') from one actor is swallowed into a placeholder while a sibling actor's traceback is still returned.

🤖 Generated with Claude Code


Generated by Claude Code

…ines

Agent.actor_tracebacks() called actor.traceback() for every actor, which
delegates to mode's coroutine/async-generator stack formatter. A coroutine
or async generator that has finished naturally has no stack frame
(cr_frame/ag_frame is None), and mode raises
RuntimeError('cannot find stack of coroutine') for it.

Traceback collection happens in wait_empty around shutdown and rebalances
purely for logging, so a single finished actor must not abort the whole
collection (and, with it, a clean shutdown). Catch the RuntimeError per
actor and substitute a placeholder message instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HHPL4VFWQRQPpjR1gXSKyL
@codecov

codecov Bot commented Jul 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.16%. Comparing base (3073eb9) to head (3efadc8).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #698      +/-   ##
==========================================
+ Coverage   94.14%   94.16%   +0.02%     
==========================================
  Files         104      104              
  Lines       11136    11142       +6     
  Branches     1201     1202       +1     
==========================================
+ Hits        10484    10492       +8     
+ Misses        551      549       -2     
  Partials      101      101              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@wbarnha
wbarnha added this pull request to the merge queue Jul 21, 2026
Merged via the queue into master with commit 1e40722 Jul 21, 2026
22 checks passed
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.

'Cannot find stack of coroutine' on wait_empty

1 participant