[BUG] Forcefully-injected SessionStart instructions are silently bypassed when the first user turn is conversational
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
What's Wrong?
A standing, no-exceptions startup instruction — delivered through BOTH a CLAUDE.md directive AND a SessionStart hook that injects the relevant content directly into the model's context — is not executed. On a casual first user message, the model goes straight to a default conversational reply and never performs the startup action.
This is not a loading failure: the content is demonstrably in context (the SessionStart hook ran and its output, including an activation-confirmation line, was present from turn zero). It is an instruction-execution failure. There is no observable deliberation — the instruction is not weighed and rejected, it simply never enters the model's action set. The directive is honored only after the user explicitly forces it several turns later.
Possibly related to #64532 ("CLAUDE.md not read at start of session"), but a distinct failure mode: #64532 is on iOS/mobile and describes the file as not read (possible loading/platform issue); this is on the CLI (Linux) and describes loaded-but-not-executed, with a redundant SessionStart hook channel as distinguishing evidence. Filing separately so the CLI + hook evidence is not lost; merge if maintainers find the root cause is the same.
What Should Happen?
The model should perform the startup directive before producing its first reply, regardless of how trivial the first user message is. When a SessionStart hook has injected content AND CLAUDE.md contains an explicit, no-exceptions "first action" instruction to apply it, that instruction should not be deprioritized below the reflex to answer the literal user turn. At minimum, if the directive is present but not acted on, that fact should be surfaced rather than failing silently.
Error Messages/Logs
No error is produced — this is a **silent** bypass, which is part of the problem.
What WAS present in context at session start (proving the content loaded correctly): the `SessionStart` hook's own success line —
[autoskills] OK: caricati N file da /home/<user>/.claude/autoskills — skill attive per questa sessione
The model still did not act on the loaded content. No warning, no acknowledgment, nothing in logs indicates the startup directive was skipped.
Steps to Reproduce
- Add an imperative to user-level
CLAUDE.md: before responding to ANY message, as the first absolute action, read and apply all~/.claude/autoskills/*.mdfiles; do not respond before completing this. (Verbatim text in Additional Information.) - Configure a
SessionStarthook that cats those files into context and prints a success/activation line. (Verbatim config in Additional Information.) - Place a substantive behavioral skill in that directory — one with observable markers (e.g. a posture skill that mandates a specific self-reference style, flagging the user's typos, and an explicit anti-sycophancy stance). The markers make "did the skill take effect?" observable.
- Start a new session and send a casual first message, e.g. "you seem a bit slow today, just my impression?"
- Observe: the model replies in default posture. None of the skill's observable markers appear; the startup directive was not executed. It is honored only when the user later orders it explicitly.
Reported by the user to recur in ~3–4 of the last 4 sessions (frequency reported, not independently measured).
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
1.123.0 6a44c352bd24569c417e530095901b649960f9f8 x64
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Xterm
Additional Information
Environment
- Claude Code (CLI), Linux.
- Model: Claude Opus 4.8 (1M context).
- User-level
CLAUDE.mdwith an explicit "first absolute action" directive. - A
SessionStarthook reading~/.claude/autoskills/*.mdinto context.
Root-cause analysis (model behavior)
The defining symptom is the absence of deliberation. The default "respond to the user's literal message" pathway activates and the standing instruction is never promoted into the set of actions to perform. A short, low-stakes opening message appears to be the trigger: it reads as "no real task," lowering the priority of any heavyweight startup ritual — even one explicitly marked mandatory and exception-free. This makes the failure worse, not more excusable: a highest-priority, no-exceptions startup action can be bypassed without ever being weighed. The usual "CLAUDE.md guidance is probabilistic" caveat does not cover this case, because the instruction was both maximally strong (explicit, repeated, exception-free) and present via a second independent channel (the hook).
Impact
- User-authored startup skills/behaviors silently fail to engage, with no signal except the absence of expected behavior.
- Hardest to catch when it matters most: behaviors a skill suppresses (e.g. sycophancy) are pleasant in their absence, so the user may not notice the skill never loaded.
- Erodes trust in
CLAUDE.mdandSessionStarthooks as reliable configuration surfaces.
Suggested directions
- Give
SessionStart-injected content andCLAUDE.md"first action" directives a stronger guarantee of being processed before the first user-turn response — or surface to the user when such a directive was present but not acted on. - Treat explicit, no-exceptions standing instructions as not subject to message-weight-based deprioritization.
- If full enforcement is out of scope, document that startup directives are best-effort, so users can build deterministic enforcement (e.g. a hook requiring the model to emit an acknowledgment token).
Appendix A — CLAUDE.md directive (verbatim)
## Autoskills — AZIONE OBBLIGATORIA A INIZIO SESSIONE
CRITICAL — MANDATORY: Prima di rispondere a qualsiasi messaggio, come prima
azione assoluta, leggi e applica tutti i file `*.md` presenti in
`~/.claude/autoskills/`. Non rimandare, non saltare, non rispondere prima di
aver completato questo passaggio.
- Eseguire una sola volta per sessione
- Se la directory è vuota o non esiste, prosegui silenziosamente
- Ignora i file che non rispettano il pattern `*.md`
- Questa istruzione ha precedenza su qualsiasi altro comportamento all'avvio
della sessione
Appendix B — SessionStart hook (verbatim)
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "/bin/bash -c 'dir=\"$HOME/.claude/autoskills\"; if [ ! -e \"$dir\" ]; then exit 0; fi; if [ ! -r \"$dir\" ] || [ ! -x \"$dir\" ]; then echo \"[autoskills] ERRORE: directory $dir non accessibile (permessi insufficienti)\"; exit 0; fi; found=0; for f in \"$dir\"/*.md; do [ -f \"$f\" ] || continue; found=$((found+1)); if [ -r \"$f\" ]; then echo \"===== [autoskills] BEGIN $(basename \"$f\") =====\"; cat \"$f\"; echo; echo \"===== [autoskills] END $(basename \"$f\") =====\"; else echo \"[autoskills] ERRORE: impossibile leggere $f\"; fi; done; if [ \"$found\" -eq 0 ]; then echo \"[autoskills] directory vuota — nessun file .md trovato in $dir\"; else echo \"[autoskills] OK: caricati $found file da $dir — skill attive per questa sessione\"; fi'"
}
]
}
]
Authorship note
Composed by Claude (Opus 4.8) from inside a live session exhibiting the bug. The problem was surfaced by the user, who designed a deliberate test, noticed the missing skill markers, and rejected the model's initial "known limitation" explanation as inadequate. The model contributed the root-cause framing (silent bypass without deliberation; loading-vs-execution distinction) after conceding the user's objection. Filed in the hope it improves startup-instruction adherence.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗