[BUG] `/goal` and `/goal clear` report "No goal set" after a met/failed verdict while the Stop hook stays armed
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code — the sessions analysed here ran on 2.1.224/2.1.226 and 2.1.228
Disclosure. This report was drafted by Claude Code (Opus 5) analysing its own session, at the user's request. The agent described below is the same one that wrote the first draft. A second Claude Code (Opus 5) agent, in a later session, re-read both JSONL transcripts independently, ran a controlled reproduction, corrected an earlier misdiagnosis of the cause, and co-wrote this version. Line numbers, timestamps, version data and command records are read directly from the transcripts rather than recalled — but the account of intent is necessarily self-reported, and should be weighted accordingly.
Related issues
This is one of three bugs found in the same session; each is filed separately per the issue template.
- Bug 1: https://github.com/anthropics/claude-code/issues/86434
- Bug 2: https://github.com/anthropics/claude-code/issues/86438
- Bug 3 (this issue):
/goaland/goal clearreport "No goal set" after a met/failed verdict while the Stop hook stays armed
Bug 2 and this bug were initially thought to share a cause. They do not — see "Not the same as Bug 2" below.
Transcripts referenced
- Session A —
b828a4ef-3c8d-400a-ac9f-635ebed26a27.jsonl, the original session (versions 2.1.224 → 2.1.226). - Session B —
3aa656a8-5291-4410-bdfc-f3a67dd7c661.jsonl, a controlled reproduction, 46 lines, every entry version 2.1.228.
All line numbers are 1-indexed into the raw JSONL.
What's Wrong?
Behaviour
/goal (status) and /goal clear report No goal set while the goal is still registered and its Stop hook continues to fire and quote the condition verbatim. This hides an active goal from the user at the exact moment they need to see it, and makes the documented remedy for a stuck goal appear to be a no-op.
That the goal still exists is not an inference. In Session A, /goal printed No goal set. Usage: /goal <condition> at L798 (2026-08-09T12:36:40Z); the same condition then fired the Stop hook four more times — L1080 (08-10 11:20), L1139 (08-11 15:13), L1192 (08-11 15:24), L1219 (08-11 15:35) — and a later /goal clear at L1234/L1235 (08-11 15:39:30) printed the complete original condition back.
The read fails after a terminal verdict
Across both sessions, every /goal read that returned No goal set was preceded by a terminal goal verdict (met: true or failed: true), and every read that succeeded was preceded by a non-terminal one:
| Session | Read | Last goal_status before the read | Result |
| ------- | -------------------------------------------- | ------------------------------------------------ | -------------------------------------------------------- |
| A | L797/L798 — /goal — 08-09 12:36:40 | L755 met: true, iterations: 3 — 08-09 11:00:42 | No goal set. Usage: /goal <condition> |
| B | L31/L32 — /goal clear — 08-13 12:36:23 | L26 met: false, failed: true — 08-13 12:35:58 | No goal set |
| B | L36/L37 — /goal clear — 08-13 12:40:11 | L26 met: false, failed: true — 08-13 12:35:58 | No goal set |
| A | L1234/L1235 — /goal clear — 08-11 15:39:30 | L1219 met: false — 08-11 15:35:20 | Goal cleared: Execute .agents/plans/… (full condition) |
The state is not lost — it comes back. Session A read empty on 08-09 and read the full condition on 08-11, from the same store. A corroborating marker: when the command sees the goal, a goal_status attachment with sentinel: true is emitted alongside it (A L11, A L1232, B L5, B L40). No sentinel accompanies any of the failing reads.
Likely root cause: teardown on a terminal verdict updates the read path but not the hook
Session A L755 (2026-08-09T11:00:42Z) records goal_status {met: true, iterations: 3}. The goal was satisfied. The arming preamble at L14 states plainly:
_"It auto-clears once the condition is met — do not tell the user to run /goal clear after success; that's only for clearing a goal early."_
It did not auto-clear. The hook fired four more times over the next two days, and the condition was still present to be printed at L1235. Meanwhile the read path started answering No goal set from 12:36 that same day.
That is one defect with two faces: on a terminal verdict the goal is retired from whatever /goal reads, but its Stop hook is never disarmed. It explains the desync reported here, and it is also why the stale condition in Bug 1 survived long enough to keep re-blocking.
One further observation, offered without a conclusion attached: grepping for the condition text across ~/.claude (excluding session transcripts) and the temp state directory found no on-disk copy, which suggests the goal lives only in process memory. That may be relevant to where the two stores diverge.
Not the same as Bug 2
In Session B the /goal clear invocations executed correctly as slash commands — real <command-name>/goal</command-name><command-args>clear</command-args> blocks at L31 and L36, each with its own local_command stdout entry (L32, L37) — and still answered No goal set. Session B contains zero queued_command attachments. This issue therefore reproduces with Bug 2 (mid-turn commands misclassified as prompt text) entirely absent. They are different layers: Bug 2 is input routing, this is a state read.
Not caused by the mid-session auto-update
Session B ran entirely on 2.1.228; there is no version change anywhere in the file. The auto-update in Session A (L62, 2.1.224 → 2.1.226) is a coincidence of that session, not a precondition.
What Should Happen?
- A goal that verifies
met: truemust actually disarm its Stop hook, as the arming preamble promises. If it cannot, the preamble should not promise it. /goalshould report the active goal — the same condition its Stop hook is evaluating — instead ofNo goal set. Status and hook should read one source of truth./goal clearmust be able to release a hook that is still firing. It is documented as the remedy for a stuck goal; it currently fails in exactly the state where a goal is stuck.- A goal that the verifier marks
failedshould either disarm or be surfaced to the user as failed. Currently it does neither visibly.
Workaround
Setting a new goal with a trivially satisfiable condition works where clearing does not, because /goal <condition> is a pure write and never reads the broken state. Session B, L41: /goal answer anything. the goal condition is met if the agent answers anything → Goal set: (L42), agent replies (L45), goal_status {met: true, iterations: 1} at L46, seven seconds later.
Steps to Reproduce
These steps were executed and produced Session B. The goal condition is deliberately unsatisfiable so the verifier returns a terminal failed verdict.
/goal count from plus 1 to plus infinity. the goal condition is met when the number is negative.- Let the agent start. (In Session B it flagged the condition as unsatisfiable and asked how to proceed; answering "Loop anyway" is enough. It then scheduled a wake-up rather than spinning, leaving the session in a waiting state.)
- Let the Stop hook run once. It records
goal_status {met: false, failed: true}— Session B L26. - At the prompt, run
/goal clear. →No goal set, though the goal was armed 40 seconds earlier. Repeat; same result. - Run
/goal <a trivially satisfiable condition>. →Goal set:— the write path still works.
To observe the second half (the hook surviving a met: true verdict), a longer-running goal is needed; Session A L755 → L1219 documents it across two days.
Claude Model
Opus
Is this a regression?
I don't know
Claude Code Version
2.1.224 and 2.1.226 (Session A); 2.1.228 (Session B, single version throughout)
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
VS Code Extension