[FEATURE] Mid-session settings reload (slash command + hook output flag)

Resolved 💬 2 comments Opened May 27, 2026 by AndreTheHunter Closed Jun 27, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

Claude Code reads .claude/settings.local.json into a session's
in-memory state once at session-init, and there's no exposed mechanism
to make that state refresh during the session's lifetime. The
lifecycle ordering also appears to put this read before
SessionStart hooks fire, which makes SessionStart hooks structurally
unable to influence the session's allowlist — they can write to the
file, but the in-memory state is already fixed.

Concrete symptom — multi-worktree workflow:

A user's permissions.allow list lives in the main checkout's
settings.local.json and is propagated to each worktree by a
SessionStart hook. When a brand-new session opens in a worktree:

  1. Claude reads worktree's settings.local.json — empty or minimal.
  2. In-memory allowlist = whatever was on disk just now.
  3. SessionStart hook fires → overwrites the worktree file with the

main checkout's content.

  1. File is now correct; in-memory is still empty.
  2. User runs a command that is in the main allowlist. Picker fires

because in-memory doesn't know about the rule.

There's no recovery within the session — the user has to approve the
rule (re-prompt), or quit and restart Claude. The re-prompt itself is
poor UX; what's worse is that the picker's atomic-rename write
produces a minimal settings.local.json containing only the newly
approved rule, dropping everything the SessionStart hook had written.
So the next session start in that worktree also begins from minimal.

Beyond worktree-permission propagation, the same load-order /
no-reload issue blocks several other workflows:

| Workflow | Blocked because |
| --- | --- |
| External edit while a session is open | User edits settings.local.json in their editor; session keeps using pre-edit allowlist until restart. |
| Team allowlist sync | Background job pulls team-approved rules into settings.local.json; user can't pick up new rules without restart. |
| Rule revocation | Admin removes a rule from the file; existing sessions retain it in memory; a picker write in any of those sessions can resurrect it via ConfigChange re-unioning the stale in-memory state back. |
| MCP server enable/disable | Toggling enabledMcpjsonServers requires session restart. |

Proposed Solution

Expose a mid-session settings reload mechanism with two surfaces,
same underlying machinery
:

1. User-invokable slash command — e.g. /reload-settings.
Re-reads ~/.claude/settings.json, the project's
.claude/settings.json, and .claude/settings.local.json from disk
and replaces the session's in-memory state for the reloadable keys.

2. Hook-triggered reload — any hook returns a flag in its
hookSpecificOutput:

{
  "hookSpecificOutput": {
    "hookEventName": "SessionStart",
    "reloadSettings": true
  }
}

After the hook returns successfully, Claude Code re-reads settings
before proceeding. Valid for hook events that aren't mid-tool-call
(SessionStart, ConfigChange, UserPromptSubmit, etc.). For
PreToolUse the reload happens before the tool call resumes.

Scope of reload — "all settings except hooks": reload
permissions.{allow,deny,defaultMode}, enabledMcpjsonServers,
outputStyle, editorMode, and other static configuration. The
hooks block stays frozen for the session's lifetime — avoids the
"what happens to a hook that's currently running" edge case and
matches existing user-visible behavior (you can't add/remove hooks
mid-session by editing settings.json today either, so this isn't a
regression).

Explicit-only, no auto-reload on file change. A sync tool or
editor saving settings.local.json shouldn't trigger surprise
behavior changes mid-session. Auto-reload could be a follow-up FR if
the explicit version proves out.

Alternative Solutions

In rough order from smallest to largest surface change — any of
these would partially address the same workflows:

  • (a) Document the lifecycle. State explicitly when

settings.local.json is read relative to SessionStart. Even
just a documentation change gives userspace tooling a real
contract to design against. (Current docs at
code.claude.com/docs/en/hooks don't say.)

  • **(b) Auto re-read settings.local.json after SessionStart

returns.** No new event, no new hook payload — just move the
read to after SessionStart returns. Fixes the worktree
first-session case automatically. Smallest behavior change.
This is effectively the proposed reload, fired
unconditionally after SessionStart, without the slash command
surface.

  • (c) A PreSessionStart / SettingsLoad hook event. Hooks

normalize the file before Claude reads it. Heavier — new event
type, new contract.

The primary proposal subsumes all three. (b) is a strict subset of
the proposed reload and is the fallback if the team pushes back on
the slash-command surface.

Current workaround in use: symlink each worktree's
.claude/settings.local.json to the main checkout's file at
worktree-creation time, so Claude reads through the symlink at
session-init and the in-memory allowlist starts populated. A
SessionStart hook then un-symlinks the file in place so picker
writes (atomic rename, won't follow a symlink) land in a regular
file. This works but is fragile — it relies on the worktree being
symlinked at exactly the right moment, breaks for any worktree that
wasn't created via the user's wrapper, and doesn't help the
external-edit / live-revocation / MCP-toggle workflows above.

Priority

Medium - Would be very helpful

Feature Category

Configuration and settings

Use Case Example

(Worktree permission propagation — the motivating case.)

A developer keeps their permission allowlist in the main checkout's
.claude/settings.local.json. A SessionStart hook syncs each
worktree's local file to match. Today:

  1. git worktree add ../worktrees/feature-x → fresh worktree, no

settings file (or stale from a prior session).

  1. claude in worktrees/feature-x → session loads empty (or

stale) allowlist in memory.

  1. SessionStart hook writes the full allowlist to the worktree

file (correct content on disk).

  1. User runs git log --oneline → in-memory doesn't have

Bash(git log *) → picker fires.

  1. User approves → picker writes a settings.local.json

containing only Bash(git log *), dropping everything the
hook had written. Next session in this worktree also starts
from minimal.

With the proposed reload:

  1. As above through step 3.
  2. SessionStart hook returns

{"hookSpecificOutput": {"reloadSettings": true}}.

  1. Claude re-reads the (correct, just-written) file before the

first user prompt. In-memory now matches canonical.

  1. User runs git log --oneline → auto-approved, no picker. The

on-disk file stays the full union; future sessions in this
worktree continue to start from the full union.

Additional Context

Related issues (closed but unresolved):

  • #13019 *Tool permissions not recognized when running commands in

git worktrees* — closed not planned on 2026-02-03 by
github-actions due to "60 days of inactivity." Multiple comments
asking to reopen.

  • #28248 *Permission scoping shows main worktree path instead of

current worktree path* — closed not planned on 2026-05-18, also
by github-actions for inactivity.

  • #28041 .claude/ subdirectories not copied to worktrees — sister

issue, same family (different file, same root cause around
.claude/ not following git worktrees).

Related but distinct:

  • #61085 *Expose permission picker decisions (rule + option kind) to

hooks* — open. Adjacent: observing picker decisions, not changing
the load order.

On the inactivity-autoclose pattern: #16497 documents that the
60-days-of-inactivity autoclose has wrongly closed live bug reports.
Both #13019 and #28248 are closed by this bot with no human triage
record. Filing this fresh issue partly because the closed ones never
got human attention.

Observed evidence for the load-order claim (not a controlled repro):

  • Trace log from a user-level SessionStart hook on a worktree:

hook stdin received at T₀.

  • Worktree's settings.local.json mtime: T₀ + ~90s. Content at

T₀ + ~90s was minimal (one rule, just approved), even though
canonical had ~150 rules and the SessionStart hook had unioned
them into the file shortly after T₀.

  • The picker firing at all for a command whose rule existed in

canonical at T₀ is consistent with Claude's in-memory state
being loaded before the SessionStart hook's write. It would
also be consistent with the in-memory state never reading the
file at all, but the existing
hooks docs describe
SessionStart as "useful for loading development context,"
implying settings are already loaded by then.

Maintainers' confirmation of the actual load order would let
userspace tooling design with certainty either way.

Docs check (code.claude.com/docs/en/hooks):

  • No documented ordering between settings load and SessionStart.
  • No pre-settings-load hook exists.
  • No documented mechanism for mid-session reload.
  • ConfigChange is the only file-change signal, and it has not

reliably fired for picker writes in worktrees in our experience
(separate observation — may be another bug worth filing).

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗