For the complete documentation index, see llms.txt. This page is also available as Markdown.

FAQ

Answers to questions Vale users ask most often.

If none of these covers your case, ask in Discord.

Scopes and markup

When should I use the raw scope?

Use it only when a rule needs to match markup syntax itself — an asterisk, a link target, a heading tag. Everything else should use a normal scope.

raw gives a rule the unprocessed file contents, which means no scope-related feature applies to it. That is the point of the scope, and also its cost.

Why doesn't my raw rule skip code blocks?

Because raw bypasses the processing that skips them. Vale already ignores listing blocks and inline literals by default, so a rule like this fires inside code you meant to exclude:

extends: existence
message: "Use uppercase letters for hexadecimal numbers"
scope: raw
level: error
raw: '\b0x[0-9a-f]*[a-f][0-9a-f]*\b'

Remove scope: raw and it behaves as intended:

extends: existence
message: "Use uppercase letters for hexadecimal numbers"
level: error
raw: '\b0x[0-9a-f]*[a-f][0-9a-f]*\b'

Why can't I disable a raw rule with a comment?

Comment processing happens after a document is converted to HTML, and raw rules don't run on the converted document. No markup-related feature — comments, ignore patterns — reaches them.

This is another reason to reach for raw only when targeting markup syntax.

How do I turn a rule off for one paragraph?

Use markup-based configuration:

How do I check whether a word is italicized?

Target the markup with raw:

How do I check that an image has alt text?

A raw-scoped rule can match the empty-alt form:

How do I stop Vale spell-checking image alt text?

When AsciiDoc images have no explicit alt text, Asciidoctor derives one from the file path, and Vale then checks it. A TokenIgnores pattern skips them:

Providing real alt text is the better fix.

Why doesn't TokenIgnores work on AsciiDoc cross-references?

Because the text Vale sees is the rendered link text, not the source. This cross-reference:

lints "Subchapter". Without a label, it lints the anchor name instead:

Give the reference a label suited to linting:

How do I ignore a reStructuredText directive?

With a BlockIgnores pattern:

Why doesn't occurrence count across the whole document?

occurrence counts within each block that the scope matches. With scope: heading, this checks whether the token appears twice in a single heading:

To count across the document, widen the scope and match the markup:

How do I lint a .txt file as reStructuredText?

Use a format association:

The --ext flag also works, but only from the command line and only for single-file or all-rst input. A format association applies everywhere, including editor extensions and mixed-format runs.

How do I get markup features in source-code comments?

Assign an embedded markup syntax to the format, then use the markup keys as normal:

How do I lint YAML?

Write a view that extracts the fields you care about:

Rules can then target those scopes individually:

Your default text-scoped rules run on them too.

Why don't IgnoredScopes and TokenIgnores work on my file?

They apply only to supported formats. For anything else, Vale has no markup to reason about, so there is nothing for those keys to select.

The other cause is a section that doesn't match the file. A section names files as they are on disk, so a format association doesn't make [*.md] reach a .qmd—that needs [*.qmd]. A section keyed on a path needs to be written relative to where you run Vale.

No. There is no scope more specific than raw for this, and matching a link target reliably from raw text is difficult because the scope is so wide.

Checking link targets is closer to what a format-specific tool does than to prose linting.

Can I enforce a reference style in AsciiDoc?

Yes, with scope: raw, since the rule needs to see the markup itself. There are AsciiDoc-specific examples in rohennes/vale-asciidoc.

How does Vale parse AsciiDoc?

It doesn't. Vale operates on the HTML that Asciidoctor produces.

How do I set Asciidoctor up as the parser?

Make sure asciidoctor is on your $PATH. Any standard installation puts it there.

Where does Vale look for a global config on Windows?

%UserProfile%, as Go's UserHomeDir defines it.

How does Vale split text into tokens?

It depends on the rule's extends value and its scope. The matching process for existence is described on its reference page, and by default a rule sees text with markup syntax removed.

Vale Studio shows the final regex a rule compiles to, which is usually the fastest way to understand a surprising match.

Writing rules

How do I disable a single rule?

Permanently, set it to NO in your .vale.ini:

For a one-off run, use a filter:

How do I disable rules for one sub-directory?

To skip a directory entirely, use --glob.

To change configuration for it, add a section to the root .vale.ini — you don't need a second config file:

Can I use lookarounds in a pattern?

Yes, in existence-based rules, since v2.9.0.

Why doesn't my sequence rule match?

Two mistakes are common. pos is not a supported key — the key is tag — and ^ matches the start of a line, not a sentence. A working version:

How do I match a word only when it isn't followed by a noun?

Negate the final token:

Can a conditional rule accept plurals?

Yes — write the plural into both patterns:

Can I flag a variable that's imported but never used?

It's better suited to a syntax linter, but it is possible:

How do I stop a substitution rule firing on valid phrasing?

Exclude the valid forms with a lookbehind:

Why doesn't my pattern match next to punctuation?

Vale adds word boundaries (\b) automatically, which interferes with patterns that need to match punctuation. Set nonword: true to turn that off — see substitution.

Why doesn't repetition catch "text text."?

The trailing punctuation makes the two tokens different: text is not text.. Adjust the pattern to exclude it:

How do I match a word only when it starts a sentence?

Combine a scope with a lookbehind:

Can I use the same %s twice in a message?

Yes, by index:

How do I replace a capture group with its uppercase form?

Substitution can't transform a match, so use a script fix.

How strict should capitalization be?

1.0 is the strictest setting. At that level, expect to maintain a vocabulary so brand and product names don't raise false positives.

Vocabularies and spelling

What's the difference between Vale.Spelling and spelling?

They are the same thing: Vale.Spelling is an implementation of the spelling check that uses the built-in dictionary. Write your own spelling-based rule only when you need a custom Hunspell dictionary — another language, or one of your own — and then use it instead of Vale.Spelling, not alongside it.

How do I accept a multi-word phrase?

Spell check is a single-word operation, so a phrase needs two rules. First, stop the unusual word raising a spelling error:

Then enforce the phrase itself:

How do I accept a term without accepting it in handles and emails?

Make the vocabulary entry case-sensitive:

Vaadin then passes Vale.Spelling, while @vaadin doesn't gain a case suggestion.

Why doesn't my accept.txt entry work?

Entries are regular expressions, so a pattern that looks right may match nothing. [dD]eserializer(s) requires a literal s; you almost certainly want [dD]eserializers?.

Why does adding a word to accept.txt stop my other rules firing on it?

A vocabulary entry is a global exception — every rule honours it. To except a word from one rule only, add it to that rule instead of the vocabulary.

Can I change the wording of a spelling message?

Yes. Write your own rule that extends spelling with the message you want.

Why are both "favour" and "favor" accepted?

Both spellings are in Vale's default dictionary. For a single-variant check, supply a custom dictionary.

How do I ship vocabularies in a package?

Vocab is a global setting, and the vocabulary rules need the Vale style enabled:

How do I structure a package containing scripts and dictionaries?

From v3.0, every non-style resource lives under <StylesPath>/config:

Configuration and packages

Why does vale sync fail with a mkdir error?

The directory named by StylesPath has to exist before you sync:

How do I override an entry in an inherited style?

Add the term to a vocabulary; vocabulary entries take precedence over an inherited rule's list.

CI and editors

Can I report every alert but only fail on some files?

Not with a built-in option. Take Vale's JSON output and set the exit code from the file paths in it.

Other

How do I enforce one sentence per line?

A script rule gives finer control.

Does Vale know parts of speech?

Yes — the sequence check matches on part-of-speech tags. The Package Explorer has working examples.

Last updated