Claude Code Settings Check vs. reading the settings.json by eye
Reading a short settings.json with one obviously empty hook command catches that command. It reliably misses a matcher regex that looks fine but fails to compile, a permission rule with one stray parenthesis, a rule duplicated across allow/deny/ask, and a rule that quietly contradicts itself between settings.json and settings.local.json — which is what this free, no-upload checker computes exactly, in one pass.
Where reading it yourself stops being enough
Anyone editing a settings.json already does this: read the hooks and permissions
blocks and decide whether they look right before trusting them to fire unattended. For a single hook with
an obviously empty command, that read catches it. The problem is the other checks below are
not the kind of thing a skim of rendered JSON reliably surfaces, especially once a project carries a
committed settings.json and a personal settings.local.json side by side.
| What you're trying to confirm | Reading the settings.json yourself | This checker |
|---|---|---|
A hook entry has an empty or missing command. | Works. This is the one case a plain read reliably catches. | Also catches it, in the same pass as everything below. |
A hook matcher regex compiles at all, rather than just looking like plausible syntax. | A string like Bash( reads as ordinary regex text; nothing about it looks wrong until something tries to compile it. | Actually compiled, the same way every time, against every matcher in the file. |
| A hook event or type name matches this tool's documented list, as a caution against a typo. | Requires recognizing nine event names and one hook type from memory while reading. | Checked against a dated reference list automatically. |
| A permission rule string has balanced parentheses, a single non-empty specifier, and no stray whitespace. | A rule with one extra or missing parenthesis reads as roughly right at a glance. | Parsed and checked against the exact grammar, every rule. |
| A rule appears more than once within one list, or in more than one of allow/deny/ask. | Easy with three or four rules; easy to miss once a file accumulates dozens across a project's history. | Every rule compared against every other rule in both files, exactly. |
| A rule in settings.json contradicts one for the same specifier in settings.local.json. | Each file reads as correct in isolation; most editors don't show both side by side. | Both files' full rule lists compared against each other, rule by rule. |
| Re-checking an entire settings.json (and its local override) again after adding or editing one hook or rule. | One hook or rule at a time, remembered by hand, every time something changes. | One paste, both files, every time. |
A quick read is still the fastest way to catch an obviously empty command in a short file, and this
checker is not doing anything a careful line-by-line audit couldn't — it is reading the same
hooks and permissions blocks a careful audit would, just compiling every matcher
and comparing every rule automatically instead of leaving the comparison to be remembered by hand.
This tool needs no account and no sign-in: the browser page parses JSON you paste entirely in your own browser. It never sends your settings anywhere.
Common questions
Can't I just read my settings.json myself?
For a short file with one hook and an obviously empty command, yes -- that case is visible on a single read. What reading does not reliably catch is a matcher regex that looks like valid syntax but fails to compile, a permission rule with one extra or missing parenthesis, a rule duplicated across allow/deny/ask, or a rule that contradicts itself between settings.json and settings.local.json. Those need every rule and every matcher checked the same mechanical way, not remembered while skimming a file with a dozen hooks and rules in it.
Why is a regex that fails to compile easy to miss on a read-through?
Because a matcher string like Bash( or [unclosed reads as plausible regex syntax at a glance -- nothing about the shape looks obviously wrong until something actually tries to compile it. A hook behind a broken matcher never fires and produces no error, no log line, and nothing to notice; the only way to know is to run the same compile step this tool runs, against every matcher in the file, not skim the string and judge it by eye.
Why is a cross-file contradiction between settings.json and settings.local.json easy to miss?
Because each file reads as correct in isolation -- a deny in the shared, committed settings.json and an allow for the exact same rule string in your own settings.local.json are two ordinary-looking lines in two files most editors don't show side by side. Catching the contradiction means holding both files' full rule lists in mind at once and comparing them rule by rule, which is a pairwise check a tool runs the same way every time and a person reviewing one file at a time does not.
What about a rule duplicated across allow, deny, and ask?
A rule string repeated in two of the three lists, or twice within one list, does not look wrong on its own -- each occurrence is a valid rule. Noticing the repeat means comparing every entry in allow against every entry in deny and ask, which is easy with three or four rules and easy to miss once a settings.json accumulates dozens across a project's history.
Is this page making a live comparison against a tool or company?
No. This page describes a manual habit anyone editing a Claude Code settings.json already has -- reading the hooks and permissions sections by eye before trusting them. It names no competing product or company. The checker itself makes no network request of any kind: the browser page parses pasted JSON in your own browser, and nothing you paste is ever uploaded.