posttooluse-validate: regex matches fire inside JSDoc and line comments — false positives on documentation prose
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 287
- Forks
- 58
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 17
Description
TL;DR
hooks/posttooluse-validate.mjs applies validation regexes line-by-line without first stripping comment ranges. Any matching phrase inside a /** */ JSDoc block, /* */ block comment, or // line comment fires a validator error, pointing at a line number inside the comment even though the actual code is correct.
Plugin version: 0.24.0.
Concrete example
// src/lib/supabase/server.ts
/**
* Server-side Supabase client factory.
*
* Note: cookies() is async in Next 16 — we await it below.
*/
import { cookies } from 'next/headers'
export async function createServerSupabaseClient() {
const cookieStore = await cookies() // line 12 — correct usage
// ...
}
Validator output (observed repeatedly in a real Next.js 16 + Supabase session):
❌ posttooluse-validate error:
src/lib/supabase/server.ts:5 — "cookies() is async — use await"
Line 5 is inside the JSDoc block. Line 12 has the correct await cookies() call. The validator's regex matched the JSDoc phrase "cookies() is async" and emitted a false error.
Three distinct repeats in one 3-hour session. All three times the operator had to manually check the actual code before dismissing the error. Trust in the validator dropped significantly — which is especially damaging because #38 already conditions the operator to suspect plugin output, so real validator hits also get dismissed.
Where
hooks/posttooluse-validate.mjs lines ~216-233 iterate source lines and apply validation regexes per-line. The matcher has no awareness of comment ranges.
Proposed fix
Before applying line-based regexes in the validation loop, strip:
- Block comments
/* ... */(including JSDoc/** ... */). Multi-line-aware. - Line comments
// ...(from//to end of line). - String literals — lower priority, causes a different class of false positives but same shape.
Options for implementation, in order of complexity:
- Preprocess with a lightweight regex-based comment stripper — applied once per file before the line iteration. Fast, good-enough for TypeScript/JavaScript. Handles ~95% of cases.
- Lightweight tokenizer — something like a minimal
tslexer that emits{kind, start, end}ranges. Excludes comment and string ranges from regex matching. More correct. - Compile file with esbuild/ts-morph once per Write — strictly correct but adds dependency weight and latency. Probably overkill.
Option 1 is likely the right trade-off for a hook that fires on every Write/Edit.
Reproducer
// File: src/test.ts
/**
* cookies() is async — this is documentation, not code.
*/
// `cookies()` is async — another documentation comment
const x = 1
Run a Write or Edit through Claude Code against this file. Validator will fire "cookies() is async" error on the JSDoc line and/or the line-comment line, even though no actual cookies() call exists.
Severity
High — a validator that fires errors on documentation prose degrades operator trust in the real errors. Combined with #38 (skill-injection noise), the compound effect is that operators disable or ignore the plugin entirely, losing the real value it provides.
Related
- #38 — architectural: project context is advisory, not authoritative. Both issues compound — skill injection noise + validator false positives → operator tunes out all plugin output.
- #51 —
matchPromptWithReasonuses unbounded.includes()for phrase matching. Same class of bug (regex/substring matching without awareness of surrounding context). - Companion issue I'm about to file: model-slug validator flags Anthropic canonical hyphen slugs (
claude-opus-4-7) as typos expecting dots. Will link here when filed.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in hooks/posttooluse-validate.mjs around lines 216-233, where source lines are iterated and validation regexes are applied. Reproduce the false positive with the provided src/test.ts example, then verify that block and line comments no longer trigger validators while real code still does. String literals are a lower-priority follow-up noted in the issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100