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
occurrence check with scope: sentence reports the alert at the wrong occurrence when a counted token repeats in a later block #1147
An occurrence rule scoped to sentence (the pattern Microsoft's SentenceLength uses) counts words correctly but reports the alert's line/column at the wrong occurrence of the counted token. When a word from the over-long sentence appears again as the start of a later block (a list item or paragraph), the alert anchors to that later match instead of to the sentence. You navigate to the reported line, find a short unrelated sentence there, and it looks like a false positive. Reproducible with a stock occurrence/scope: sentence rule and no third-party package, so it is core behavior.
styles/MyStyle/SentenceLength.yml (identical to Microsoft's SentenceLength):
extends: occurrencemessage: "Try to keep sentences short (< 30 words)."scope: sentencelevel: warningmax: 30token: '\b(\w+)\b'
repro.md — the 33-word sentence is on lines 1–4 (its second sentence starts with Replace); line 6 is a short bullet that also starts with Replace:
The `format` option is read automatically (the loader resolves it at startup
level), so leave it as-is. Replace `<preset>` with a bare name (for example
`fast`) to select that preset's defaults (colors, spacing, and margins with no
other changes), or a full path (for example `./theme.json`) to load your own.
-**Replace the renderer too.** Write the output yourself in a custom format.
Run vale repro.md.
Expected: the alert points at the long sentence, whose second sentence begins on line 2.
Actual:
repro.md:6:5:MyStyle.SentenceLength:Try to keep sentences short (< 30 words).
It is reported at line 6 — the bullet, a 12-word sentence that is not over-long. Deterministic across runs.
Confirming the cause: change the bullet's first word from Replace to any word not in the long sentence (e.g. Swap), and the alert correctly moves to repro.md:2:28 (the long sentence). The position is being resolved to a later match of a token shared with the sentence.
I suspect this is related to how anchor treats a sentence block that inline code has rewritten: when the byte offsets get skipped, placement falls back to strings.Index(ctx, txt), which might be where the wrong line creeps in.
Activity
jackwhelpton commentedon Aug 16, 2026
I suspect this is related to how
anchortreats a sentence block that inline code has rewritten: when the byte offsets get skipped, placement falls back tostrings.Index(ctx, txt), which might be where the wrong line creeps in.fix: don't treat a word before a code span as inline markup (#1147)
build(deps): update errata-ai/vale to v3.18.0