Skip to content
Latchkey

Ruby Test/Task Hangs on a Stray binding.pry / irb in CI

A binding.pry or binding.irb left in the code opened an interactive prompt during a test or task. On a non-interactive CI runner there is no stdin to answer it, so the job hangs until it times out.

What this error means

A test run or rake task stops producing output and eventually hits the job timeout. The last log line is often a Pry/IRB banner or a source listing - the process is blocked waiting for interactive input.

CI log
From: /app/app/services/checkout.rb:14 :

    13:   def process
 => 14:     binding.pry
    15:     charge!

[1] pry(#<Checkout>)>      # waits forever for stdin in CI

Common causes

A debugger breakpoint left in committed code

binding.pry / binding.irb / debugger was committed by accident. It opens an interactive session that blocks until input arrives - which never happens on a headless runner.

No TTY to answer the prompt

CI runs non-interactively with no attached terminal, so the debugger reads EOF or simply waits, stalling the job rather than continuing.

How to fix it

Remove the breakpoint and guard against it

Delete the stray debugger call, then fail CI if any are reintroduced.

Terminal
# fail the build if a debugger is committed
grep -rnE 'binding\.(pry|irb)|^[^#]*\bdebugger\b' app lib && exit 1 || true

Lint for debugger calls

  1. Enable RuboCop’s Lint/Debugger cop so binding.pry/irb fails lint.
  2. Add a pre-commit hook or CI grep step to block debugger calls.
  3. Set a sensible step timeout so a hang fails fast instead of burning minutes.

How to prevent it

  • Enable RuboCop Lint/Debugger to catch stray breakpoints.
  • Add a CI grep/pre-commit check for binding.pry / binding.irb / debugger.
  • Keep job timeouts tight so an accidental hang fails quickly.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →