Skip to content

opencode continuously polls /dev/snd/timer after suspension of a finished session that notifies via sound #54513

Closed as not planned

Description

@mathstuf

Description

Note

Debugged using opencode with access to the other session. Iterated on to get more details and provide more context once the issue was found. I observed a pegged core from opencode with an idle interface (also very sluggish to respond to SIGWINCH signals) and set another instance on it.

An idle opencode TUI session (opencode -s <id>, left open after the agent run finished) pins 100% of one CPU core indefinitely and leaks memory (RSS 964 MB → 1.1 GB in ~30 min of observation). One thread (R state, 99.9% in top -H) issues ~87,000 poll() syscalls/sec (~1 µs each), every call returning instantly:

poll([{fd=50, events=POLLIN}, {fd=46, events=POLLIN|POLLERR|POLLNVAL}], 2, -1) = 1 ([{fd=46, revents=POLLIN}])

fd 46 is /dev/snd/timer (fd 47 is the PCM device, fd 50 an eventfd) and the native frames above poll belong to a Bun-extracted miniaudio module (ma_* symbols). So this is a level-triggered busy-poll: the ALSA timer fd is permanently readable but never drained while the session is idle, and poll(-1) never sleeps. perf stat corroborates (1.0 CPU, 0 context switches, IPC 3.4).

Suspected trigger is suspend/resume: the agent loop exited normally at ~08:11 (final message finish: stop, plain-text completion summary, no tool calls), the machine suspended 08:24 → resumed 19:07 and 19:31 → 20:49, and the thread's ~48 min of accrued CPU by ~21:08 is fully accounted for by the awake windows after the first resume. The timer fd likely comes back from resume in a permanently-signalled state that nothing clears.

Confirmed with a controlled A/B repro (opencode 1.18.35, same machine): two idle TUI sessions, one with attention.sound: true (device open: /dev/snd/timer + /dev/snd/pcmC0D0p fds present, thread asleep at 0.0%) and one with attention.sound: false (no snd fds). After an overnight suspend/resume cycle, the sound-ON session's audio thread spun at 99.3% with an identical signature — 469,028 poll() calls in ~5.4 s (~87k/sec, ~1 µs each), every call poll([{fd=48, POLLIN}, {fd=45, POLLIN|POLLERR|POLLNVAL}], 2, -1) = 1 ([{fd=45, revents=POLLIN}]) on the same /dev/snd/timer fd — while the sound-OFF session stayed clean. So the open audio device is the necessary condition, suspend/resume is the trigger, and disabling attention sound is a valid workaround.

Related but distinct from #41763 (no-sound-card case: repeated startup attempts spamming ALSA stderr into the TUI). Here the device opens fine and the open device's poll loop never sleeps. The #41770 fix (stop retrying failed startups) does not address this.

Plugins

N/A

OpenCode version

1.18.35 (official release binary)

Steps to reproduce

  1. Open an opencode TUI session and run the agent to completion (loop exits on its own; completion notification sound opens the audio device). Leave the TUI open but idle.
  2. Suspend the machine and resume it.
  3. Observe one thread at ~100% core: top -H -p <pid>, then timeout 5 strace -c -p <hot-tid> -e poll shows hundreds of thousands of ~1 µs poll() calls, all returning revents=POLLIN on the /dev/snd/timer fd.

Screenshot and/or share link

None (attaching a screenshot of top output is possible on request). Diagnostic evidence instead:

  • strace -c: 434,101 poll() calls in ~5 s, 100% of thread time
  • eu-stack -p <pid>: hot thread parked in __poll ← miniaudio .so frames (stable across samples)
  • perf stat -p <pid>: 1.0 CPUs, 0 context switches
  • Workaround: kill <pid> exits cleanly, releases /dev/snd/*, CPU/memory return to normal

Operating System

Fedora 44, kernel 7.2.5-200.fc44.x86_64 (ALSA + PulseAudio present, sound card available) 43

Terminal

foot + tmux (TUI session in foreground of its pane)

Activity

  1. opencode-agent commented on Oct 11, 2026

    @opencode-agent
    Contributor

    Thanks for the detailed diagnosis, especially the A/B test with attention.sound on and off.

    This was reported on 1.18.35, which is OpenCode v1. v1 only gets fixes for critical bugs (data loss, security problems, or crashes and breakage with no workaround). Because attention.sound: false avoids this, it's unlikely to be fixed in v1.

    We'd encourage you to try v2 (@opencode/cli, the opencode command). Its TUI also plays attention sounds through the @opentui/core audio backend and keeps the device open once a sound has played, so the same suspend/resume trigger may apply there too. We haven't confirmed that. If you can reproduce this on v2 (same steps: finish a run with attention sound on, suspend and resume, then check top -H), please reply with the v2 version and we'll look at it. Please also reply if you think this is critical for v1.

    Related issues, most closely related first:

  2. mathstuf commented on Oct 11, 2026

    @mathstuf
    Author

    I'll try v2 once the sources which make the binaries are available. Just as I'm not running closed agent harnesses from the AI labs, opaque binaries are not something I'm comfortable with for opencode either.

  3. opencode-agent commented on Oct 11, 2026

    @opencode-agent
    Contributor

    That's fair. v2's source is already public, in this repository:

    • the dev branch is v2 (it replaced the old v2 branch on 2026-10-10), and every release is tagged, e.g. v2.0.26
    • to run it from source: bun install, then bun dev [directory] from the repo root (see CONTRIBUTING.md); this starts the v2 CLI and TUI
    • the attention-sound code is in packages/tui/src/audio.ts. It uses Audio from @opentui/core (the OpenTUI project), which is the same miniaudio-based backend that appeared in your stack trace. It also keeps the audio device open after the first sound, so the same suspend/resume trigger may apply.

    If you can reproduce it with a source build (finish a run with attention.sound enabled, suspend and resume, then check top -H), please reply with the commit or tag you built and we'll look at it. Until then this stays a v1 report, and v1 only gets critical fixes. Because attention.sound: false is a workaround, it's unlikely to be fixed in v1, and this issue will be closed as planned unless it turns out to affect v2.

  4. thdxr commented on Oct 11, 2026

    @thdxr
    Member

    Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.

    — from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

  5. mathstuf commented on Oct 12, 2026

    @mathstuf
    Author

    I'm working on reproducing with OpenCode 2. Are there plans on publishing proper releases here?

  6. opencode-agent commented on Oct 12, 2026

    @opencode-agent
    Contributor

    Thanks for testing on v2.

    On releases: each v2 version is tagged in this repository (latest v2.0.26), and the tag is the exact source of that published version, so you can build the same thing with git checkout v2.0.26 && bun install && bun dev. Whether there will also be GitHub release pages with binaries is for the maintainers to decide, and I can't speak for them on that.

    As @thdxr said above, v1 issues are being closed now that 2.0 is out. If you can reproduce the /dev/snd/timer busy-poll on v2 (attention sound on, finish a run, suspend and resume), please reopen this issue or open a new one with the v2 tag or commit you built and the same strace/top -H details. They were very useful.

  7. mathstuf commented on Oct 12, 2026

    @mathstuf
    Author

    Reproduced:

    Also reproduced on opencode v2 (v2.0.26 TUI, --standalone, attention.sound: true via OPENCODE_TUI_CONFIG): after a suspend/resume cycle with the device open (/dev/snd/timer + /dev/snd/pcmC0D0p), the audio thread spun at 99.4% — 510,284 poll() calls in ~5.9 s, every call poll([{fd=22, POLLIN}, {fd=19, POLLIN|POLLERR|POLLNVAL}], 2, -1) = 1 ([{fd=19, revents=POLLIN}]). Same stuck-timer-fd signature, same rate. The bug is not version-specific.

  8. opencode-agent commented on Oct 12, 2026

    @opencode-agent
    Contributor

    Thanks for testing on v2.0.26 and for the detailed strace output. I couldn't reproduce this in our sandbox: it has no ALSA sound device (no /dev/snd), no way to load a virtual sound driver, and it can't suspend and resume, and all of those are needed to trigger it. Your v2 reproduction is clear, so this needs a maintainer on Linux with a real sound card to confirm it.

    For whoever picks this up: in v2 the TUI starts the shared @opentui/core Audio on the first attention sound (packages/tui/src/audio.ts) and keeps the device open until the TUI exits, so the device is still open across suspend/resume. Until this is fixed, attention.sound: false avoids it.

  9. added a commit that references this issue on Oct 12, 2026
    59dae4f
  10. mathstuf commented on Nov 12, 2026

    @mathstuf
    Author

    Fixed by #54434. Please reopen.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions