You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Permission rules: an unreadable or unparseable settings.json drops its deny rules instead of failing closed #4282
RTK loads permissions from the Claude Code settings files. When one of those files exists but cannot be read or parsed, its rules are skipped and matching carries on as if they were not there. A command that file denies then gets the Default verdict (exit 3) instead of Deny (exit 2).
Measured
rtk rewrite "git push origin main" on develop (c75f1590), with CLAUDE_CONFIG_DIR pointing at a directory whose settings.json holds {"permissions":{"deny":["Bash(git push *)"]}}:
settings.json
exit
stderr
valid
2 (denied)
—
unparseable (a trailing comma after the array)
3
[rtk] warning: failed to parse permissions from <path>
unreadable (chmod 000)
3
(nothing)
Two different gaps:
An unreadable file is dropped with no warning at all. The read-failure branch in src/hooks/permissions.rs moves on to the next file without saying anything.
An unparseable file warns, but nobody sees it. The shell hooks call rtk rewrite "$CMD" 2>/dev/null (hooks/claude/rtk-rewrite.sh, hooks/cursor/rtk-rewrite.sh), so the warning is discarded before it reaches the user.
In both cases the deny list the user wrote stops applying, and the verdict degrades rather than failing closed.
Who this reaches
Claude Code applies its own copy of these rules, so it does not depend on RTK alone. For the delegates where RTK is the only thing reading ~/.claude/settings.json — the ones that shell out to rtk rewrite and do not distinguish exit 0 from 3 (hooks/pi/rtk.ts, also used by omp; hooks/hermes/rtk-rewrite/__init__.py; hooks/opencode/rtk.ts) — a broken file means the whole deny list is void. A change that relaxes Default for a host, such as #3909 for OpenClaw, would turn these commands from a prompt into an allowed rewrite.
Shape of a fix
A settings file that exists but cannot be read or parsed should not be indistinguishable from "no rules". Failing closed would mean treating that load failure as Ask — a verdict nothing relaxes — rather than letting every command fall to Default. The unreadable branch also needs the same warning the parse branch already gives, and a warning that only reaches /dev/null in the common path may be worth surfacing some other way.
Related: #1482 (the same silent fallback for rtk's own config.toml), #4281 (deny rules missing wrapped or env-prefixed commands).
#4287 covers the read and parse failures. One case outside its hunks still drops rules with no warning: a settings file that is valid JSON but has the wrong shape. json.get("permissions") and append_bash_rules skip anything that is not an object or an array of strings.
On develop e542dca0b and on #4287 merged, rtk rewrite "git push origin main" with CLAUDE_CONFIG_DIR/settings.json set to:
null → exit 3 with no warning; exit 0 (rewrite allowed) under RTK_REWRITE_HOST=openclaw
{"permissions":{"deny":"Bash(git push *)"}} (a string, not an array) → the same: exit 3 with no warning, exit 0 under RTK_REWRITE_HOST=openclaw
The same fail-closed Ask as an unparseable file would cover it.
#4287 is now merged on develop, not in a release yet. An unreadable or unparseable settings file now prints a warning and the command is left to ask, also under RTK_REWRITE_HOST=openclaw.
The wrong-shape case from my previous comment is unchanged on develop 2dabd83: {"permissions":null}, or a deny written as a string instead of an array, still drops the rules with no warning and exits 0 under RTK_REWRITE_HOST=openclaw. Separately, the legacy rtk-rewrite.sh hook sends rtk rewrite's stderr to /dev/null (line 59), so anyone still on that hook never sees the new warning.
Activity
rtk-wshm-sync-bot commentedon Sep 26, 2026
🔍 Automated Triage
bughighSummary
An unreadable or unparseable permissions settings.json silently drops deny rules and falls back to Default instead of failing closed to Ask.
📁 Relevant files
src/hooks/permissions.rshooks/claude/rtk-rewrite.shhooks/cursor/rtk-rewrite.shhooks/pi/rtk.tshooks/hermes/rtk-rewrite/__init__.pyhooks/opencode/rtk.tsSuggested Actions
Triaged automatically by wshm · This is an automated analysis, not a human review.
TechWizard9999 commentedon Sep 27, 2026
Hi @KuSh , Can I work on this issue
Could you please assing me this
KuSh commentedon Sep 27, 2026
Check #4287, it seems @mrhard9090 already pushed something
KuSh commentedon Oct 18, 2026
#4287 covers the read and parse failures. One case outside its hunks still drops rules with no warning: a settings file that is valid JSON but has the wrong shape.
json.get("permissions")andappend_bash_rulesskip anything that is not an object or an array of strings.On develop
e542dca0band on #4287 merged,rtk rewrite "git push origin main"withCLAUDE_CONFIG_DIR/settings.jsonset to:null→ exit 3 with no warning; exit 0 (rewrite allowed) underRTK_REWRITE_HOST=openclaw{"permissions":{"deny":"Bash(git push *)"}}(a string, not an array) → the same: exit 3 with no warning, exit 0 underRTK_REWRITE_HOST=openclawThe same fail-closed
Askas an unparseable file would cover it.fix(permissions): fail closed when a settings file cannot be read or …
KuSh commentedon Oct 23, 2026
#4287 is now merged on develop, not in a release yet. An unreadable or unparseable settings file now prints a warning and the command is left to ask, also under
RTK_REWRITE_HOST=openclaw.The wrong-shape case from my previous comment is unchanged on develop 2dabd83:
{"permissions":null}, or adenywritten as a string instead of an array, still drops the rules with no warning and exits 0 underRTK_REWRITE_HOST=openclaw. Separately, the legacyrtk-rewrite.shhook sendsrtk rewrite's stderr to/dev/null(line 59), so anyone still on that hook never sees the new warning.