Files
claudetools/.claude/memory/feedback_background_task_no_ampersand.md
Howard Enos 9340cdec17 ask-forum: promote to a full skill + wire into skill-first routing
Add .claude/skills/ask-forum/SKILL.md (usage contract, correlation model,
forum-only scope, access/permissions) and route to it from CLAUDE.md
(skill-first covered domains) + SKILL_ROUTING.md, so sessions invoke the
skill instead of hand-rolling the Discord API — the footgun that produced a
broken background wait. Capture that footgun as memory
feedback_background_task_no_ampersand (run_in_background, never a shell &).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-07 20:12:18 -07:00

2.0 KiB

name, description, type
name description type
Background tasks — run_in_background only, never add a shell `&` When launching a long-running command as a background task (run_in_background:true), do NOT also append a shell `&`/`disown`/`nohup`. The shell forks the command and exits 0 immediately, orphaning it — a blocking wait then never delivers its result. Run it in the FOREGROUND of that shell; the harness does the backgrounding. feedback

When you want a long-running command (e.g. ask-forum.sh --wait, a poll loop, a blocking watcher) to run in the background, use the Bash tool's run_in_background: true and run the command in the foreground of that shell — a bare bash script.sh ... with no trailing &, no disown, no nohup.

Why: appending & forks the command off inside the shell; the shell then reaches the end and exits 0 immediately. The harness sees exit 0 and reports the task "completed" right away, while the forked process is orphaned (and often killed). A blocking --wait that was supposed to sit for minutes and deliver an answer instead returns nothing — its result is never captured or notified.

How to apply:

  • Background wait, CORRECT: Bash(command="bash .claude/scripts/ask-forum.sh --wait <id> --timeout 1800", run_in_background=true) — the wait truly blocks server-side, costs zero tokens while pending, and the harness pings you the instant it completes.
  • WRONG: Bash(command="bash ... --wait ... &", run_in_background=true) and ... & disown — orphans the wait, "completes" instantly, no answer.
  • The two mechanisms are redundant: run_in_background IS the backgrounding. Never stack a shell & on top of it.

Incident: hit TWICE in one session (2026-07-08) building the ask-forum flow — each time the "background wait" for a Discord reply exited 0 instantly and never delivered the answer, which looked like the reply was lost and forced the user to manually prompt "did they answer?". Logged as --friction in errorlog.md. Related: ask-forum.