Skip to content

Claude adapter: Stop hook + idle detection re-entrant loop prevents session from ending #149

Description

@tronghieu

Description

When a Claude Code session running under bmad-loop finishes its work and enters the "Leavening" phase (stop hooks execution), a re-entrant loop can occur that prevents the session from ever properly ending.

Steps to reproduce

  1. Configure a Claude Code project with Stop hooks that take more than ~5 seconds to complete (e.g., a hook that runs gh CLI commands or a test suite)
  2. Run bmad-loop run with a story
  3. Let the dev/review session complete its work and attempt to stop

What happens

  1. Session finishes work → enters "Leavening" phase → stop hooks begin executing
  2. Claude Code shows running stop hooks… 0/N (the counter never progresses past 0)
  3. After ~5 seconds of hooks not completing, bmad-loop idle detection fires and writes "You appear idle in bmad-loop automation mode" into the TTY
  4. Claude sees this message as user input → tries to respond/explain → this triggers the Stop hooks AGAIN
  5. The cycle repeats: stop hooks run → idle detection → Claude responds → stop hooks run again → ...

Observed behavior

  • The stop hook counter stays at 0/N indefinitely
  • bmad_loop_hook.py Stop completes successfully each iteration (Stop events are written to the run directory)
  • But the session never transitions to session-end in the journal
  • The Claude process remains alive with an open API connection, stuck in this loop
  • Tokens continue to be consumed as Claude re-processes the idle message each cycle

Expected behavior

Stop hooks should either:

  • Complete (or timeout) before idle detection can fire, OR
  • Idle detection should not inject messages into the TTY while stop hooks are in progress, OR
  • The session should eventually end after a finite number of idle detection cycles

Environment

  • bmad-loop 0.8.0
  • Claude Code adapter
  • macOS

Impact

Sessions that are functionally complete (all work done, verification passing, commits made) cannot terminate, consuming tokens and requiring manual intervention to kill the process.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions