Lint Rules
Reference catalog of every built-in Panache lint rule, the diagnostic codes each rule emits, severity, auto-fix availability, and configuration requirements.
This page describes every built-in lint rule, with examples and advice for resolving each warning. Use a rule’s name in [lint] selection lists to enable or disable it. A rule may report several diagnostic codes for different problems.
For help running the linter and choosing rules, see the Linting guide.
Diagnostic format
Diagnostics are displayed in a compiler-style format:
severity: [diagnostic-code] message
--> file:line:column
Components:
severity-
error,warning, orinfo diagnostic-code-
The specific code emitted (e.g.,
undefined-reference-label). A single rule may emit several distinct codes. message- Human-readable description of the issue
location- File path, line number, and column number
Some diagnostics include help or note lines with advice or related locations. The rule examples below show the current output.
Severity levels
Panache uses three severity levels:
error- Errors that may prevent the document from rendering
warning- Likely mistakes or unintended output
info- Informational messages (currently unused, reserved for future use)
Fix safety
Auto-fixes carry a safety level that controls when panache lint --fix applies them:
safe-
The fix preserves the document’s meaning and only tidies syntax. Safe fixes are applied by a plain
--fix. unsafe-
The fix may change the document’s meaning (for example, deleting a key). Unsafe fixes are skipped by a plain
--fix; pass--unsafe-fixesalongside--fixto apply them too. When a run leaves unsafe fixes unapplied, the CLI prints how many are available.
In the editor (LSP), unsafe fixes are still offered as individual quick fixes (labeled (unsafe)), but they are excluded from the aggregate “Fix all auto-fixable lint issues” action, mirroring the safe-by-default CLI behavior.
Each fix example names the command needed to apply it.
Rules
Each section lists a rule’s settings and shows the diagnostics it produces. Examples use the Quarto flavor unless another flavor is specified. Fix examples state whether they require --unsafe-fixes.
heading-hierarchy
Warns when a heading skips a level, such as # Methods followed by ### Results. Use consecutive levels to make the document’s structure clear.
The fix lowers the skipped heading to the next level after the preceding heading. Review the surrounding sections if the heading belongs elsewhere.
- Default
- On
- Auto-fix
- Available; see the examples for fix safety.
Diagnostic codes
| Code | Severity |
|---|---|
heading-hierarchy |
Warning |
Examples
# Methods
### Resultswarning: [heading-hierarchy] Heading level skipped from h1 to h3; expected h2
--> example.qmd:3:1
|
1 | # Methods
| - previous heading is here
2 |
3 | ### Results
| ^^^^^^^^^^^
= help: Change heading level from 3 to 2
After panache lint --fix:
# Methods
## Resultsempty-list-item
Warns about list items with no text. Fill in the missing item or remove it.
A bare - directly below text can also turn the preceding line into a heading instead of creating an empty item. The rule warns about that form too.
- Default
- On
- Auto-fix
- No
Diagnostic codes
| Code | Severity |
|---|---|
empty-list-item |
Warning |
Examples
- First item
-
- Last itemwarning: [empty-list-item] List item has no content
--> example.qmd:2:1
|
2 | -
| ^
empty-values
Warns about YAML keys with nothing after the colon, such as title:. YAML treats these values as null, which may indicate an unfinished setting.
Supply a value, remove the key, or write null or ~ if null is intentional. The rule checks frontmatter and code-cell options, but not mappings written inside braces, such as {title: }.
The optional fix removes the whole key. It requires --unsafe-fixes because removing a setting can change the document’s behavior.
- Default
- On
- Auto-fix
- Available; see the examples for fix safety.
Diagnostic codes
| Code | Severity |
|---|---|
empty-values |
Warning |
Examples
---
title:
---warning: [empty-values] Key `title` has an empty value (implicit null)
--> example.qmd:2:1
|
2 | title:
| ^^^^^
= help: Remove the empty key `title`
= help: Provide a value, remove the key, or write an explicit `null` if the empty value is intentional
After panache lint --fix --unsafe-fixes (review the change before applying it):
---
---consumer-divergence
Warns about YAML values that Quarto and Pandoc read differently. For example, Pandoc reads no as false, while Quarto reads it as the string "no". Leading-zero values such as 0755 can also have different meanings.
Quote a value if you mean a string. Otherwise, write true, false, or a decimal integer explicitly. This check applies to Quarto frontmatter, where both YAML versions are used.
The optional fix quotes the value. It requires --unsafe-fixes because the author may have intended a boolean or number instead of a string.
- Default
- On
- Auto-fix
- Available; see the examples for fix safety.
- Requirements
- The Quarto flavor.
Diagnostic codes
| Code | Severity |
|---|---|
consumer-divergence |
Warning |
Examples
---
country: no
---warning: [consumer-divergence] Key `country`: value `no` is the boolean `false` to pandoc (YAML 1.1) but the string `"no"` to Quarto's js-yaml (1.2)
--> example.qmd:2:10
|
2 | country: no
| ^^
= help: Quote the value as `'no'`
= help: Quote the value to force a string under every consumer, or write the explicit `true`/`false` (or canonical integer) you mean
After panache lint --fix --unsafe-fixes (review the change before applying it):
---
country: 'no'
---math-syntax
Reports unbalanced braces, unmatched environments, and other structural errors inside TeX math. These errors can prevent PDF output or leave an equation missing from HTML output.
Check the indicated delimiter and add, remove, or correct its partner. The rule checks structure, not command names or mathematical meaning. If a TeX macro deliberately supplies a delimiter elsewhere, suppress this rule for that passage.
- Default
- On
- Auto-fix
- No
- Requirements
-
At least one
tex-math-*extension is enabled.
Diagnostic codes
| Code | Severity |
|---|---|
math-unclosed-group |
Error |
math-unexpected-close-brace |
Error |
math-unclosed-environment |
Error |
math-mismatched-environment |
Error |
math-unexpected-end |
Error |
math-unclosed-delimiter |
Error |
math-unexpected-right |
Error |
math-unexpected-dollar |
Error |
math-unclosed-group
An opening { has no matching }.
math-unexpected-close-brace
A closing } has no matching {.
math-unclosed-environment
A \begin{...} has no matching \end{...}.
math-mismatched-environment
The name in \end{...} differs from the open environment.
math-unexpected-end
A \end{...} has no matching \begin{...}.
math-unclosed-delimiter
A \left has no matching \right.
math-unexpected-right
A \right has no matching \left.
math-unexpected-dollar
An unescaped $ appears inside TeX math. Use \$ for a literal dollar sign.
Examples
A group is missing its closing brace:
$\frac{1}{2$error: [math-unclosed-group] unclosed `{` group
--> example.qmd:1:10
|
1 | $\frac{1}{2$
| ^
A closing brace has no matching opener:
$a}b$error: [math-unexpected-close-brace] unmatched closing brace `}`
--> example.qmd:1:3
|
1 | $a}b$
| ^
An environment is missing its end:
$$
\begin{aligned} x &= 1
$$error: [math-unclosed-environment] `\begin` without a matching `\end`
--> example.qmd:2:1
|
2 | \begin{aligned} x &= 1
| ^^^^^^
The environment names do not match:
$$\begin{aligned}x\end{matrix}$$error: [math-mismatched-environment] `\end` name does not match the open `\begin`
--> example.qmd:1:23
|
1 | $$\begin{aligned}x\end{matrix}$$
| ^^^^^^^^
An environment ends without being opened:
$x \end{aligned}$error: [math-unexpected-end] `\end` without a matching `\begin`
--> example.qmd:1:4
|
1 | $x \end{aligned}$
| ^^^^
A scalable delimiter is missing its partner:
$\left(x$error: [math-unclosed-delimiter] `\left` without a matching `\right`
--> example.qmd:1:2
|
1 | $\left(x$
| ^^^^^
A closing scalable delimiter has no opener:
$x\right)$error: [math-unexpected-right] `\right` without a matching `\left`
--> example.qmd:1:3
|
1 | $x\right)$
| ^^^^^^
A dollar sign appears inside display math:
$$
$ a
$$error: [math-unexpected-dollar] unescaped `$` inside TeX math ends math mode
--> example.qmd:2:1
|
2 | $ a
| ^
inline-math-line-break
Warns about \\ at the top level of inline math. It means a row break, so \\mathrm{x} does not mean \mathrm{x}.
Remove the extra backslash if you meant a command. If you need several rows, use display math with a suitable environment. Row breaks inside constructs such as matrix, array, and \substack are allowed.
- Default
- On
- Auto-fix
- No
- Requirements
-
At least one
tex-math-*extension is enabled.
Diagnostic codes
| Code | Severity |
|---|---|
inline-math-line-break |
Warning |
Examples
$\\mathrm{x}$warning: [inline-math-line-break] top-level `\\` is not portable in inline math
--> example.qmd:1:2
|
1 | $\\mathrm{x}$
| ^^
= help: `\\mathrm` is parsed as a line break followed by `mathrm`; use `\mathrm` if you intended a command
heading-eaten-attrs
Warns when an HTML comment after a heading’s attributes prevents Pandoc from recognizing them. The attributes then appear as text, and links to the intended heading ID may stop working.
Move the comment to its own line. A heading’s {#id .class} block must be followed only by whitespace.
- Default
- On
- Auto-fix
- No
- Requirements
-
extensions.header-attributes = true.
Diagnostic codes
| Code | Severity |
|---|---|
heading-eaten-attrs |
Warning |
Examples
# Results {#results} <!-- Draft -->warning: [heading-eaten-attrs] Comment on a heading line with `{...}` attributes; pandoc treats the brace block as literal text when anything follows it on the line.
--> example.qmd:1:22
|
1 | # Results {#results} <!-- Draft -->
| ^^^^^^^^^^^^^^
= help: Move the comment to its own line before or after the heading.
heading-strip-comments-residue
Warns about comments on a heading line that also contains attributes. Running pandoc --strip-comments removes the comment but leaves its surrounding spaces.
Move the comment to a separate line. Enable this rule if your publishing process uses --strip-comments.
- Default
- Off
Enable this rule with [lint] extend-select = ["heading-strip-comments-residue"].
- Auto-fix
- No
- Requirements
-
extensions.header-attributes = true.
Diagnostic codes
| Code | Severity |
|---|---|
heading-strip-comments-residue |
Warning |
Examples
# Results <!-- Draft --> {#results}warning: [heading-strip-comments-residue] Comment on a heading line adjacent to `{...}` attributes; `pandoc --strip-comments` will leave stray whitespace on the heading.
--> example.qmd:1:11
|
1 | # Results <!-- Draft --> {#results}
| ^^^^^^^^^^^^^^
= help: Move the comment to its own line before or after the heading.
adjacent-footnote-refs
Warns when footnote references touch, as in [^a][^b]. Their superscript numbers can run together: footnotes 7 and 8 may look like footnote 78.
The fix inserts a space between the references so readers can distinguish them.
- Default
- On
- Auto-fix
- Available; see the examples for fix safety.
- Requirements
-
extensions.footnotes = true.
Diagnostic codes
| Code | Severity |
|---|---|
adjacent-footnote-refs |
Warning |
Examples
Text[^a][^b].
[^a]: First note.
[^b]: Second note.warning: [adjacent-footnote-refs] Adjacent footnote references render as a single superscript number; insert a space to keep them visually distinct
--> example.qmd:1:9
|
1 | Text[^a][^b].
| ^^^^
= help: Insert a space between the footnote references
After panache lint --fix:
Text[^a] [^b].
[^a]: First note.
[^b]: Second note.blank-line-in-display-math
Warns when a blank line separates apparent $$ math delimiters. Pandoc ends the paragraph at the blank line, so the equation may appear as ordinary text.
Remove the blank line if the lines belong to one equation. Use separate, complete math blocks if you intended two equations.
- Default
- On
- Auto-fix
- No
- Requirements
-
extensions.tex-math-dollars = true.
Diagnostic codes
| Code | Severity |
|---|---|
blank-line-in-display-math |
Warning |
Examples
$$
x = 1
$$warning: [blank-line-in-display-math] Blank line ends the paragraph before this display-math delimiter closes, so pandoc renders both `$$` markers as literal text
--> example.qmd:1:1
|
1 | $$
| ^^
blank-line-in-inline-footnote
Warns when an apparent inline footnote crosses a blank line. Inline footnotes can wrap over ordinary line breaks, but they cannot contain several paragraphs. The ^[ and ] markers may appear literally in the output.
Remove the blank line, or use a reference-style footnote if the note needs several paragraphs.
- Default
- On
- Auto-fix
- No
- Requirements
-
extensions.inline-footnotes = true.
Diagnostic codes
| Code | Severity |
|---|---|
blank-line-in-inline-footnote |
Warning |
Examples
Text^[A note
continued here].warning: [blank-line-in-inline-footnote] Blank line ends the paragraph before this inline footnote closes, so pandoc renders the footnote markers as literal text
--> example.qmd:1:5
|
1 | Text^[A note
| ^^
footnote-ref-in-footnote-def
Warns about a footnote reference inside another footnote’s definition. Pandoc does not nest these notes, so the inner reference appears as literal text instead of linking to a note.
Include the explanation directly in the outer note, move the reference into the main text, or remove it.
- Default
- On
- Auto-fix
- No
- Requirements
-
extensions.footnotes = true.
Diagnostic codes
| Code | Severity |
|---|---|
footnote-ref-in-footnote-def |
Warning |
Examples
Text[^a].
[^a]: See [^b].
[^b]: More detail.warning: [footnote-ref-in-footnote-def] Footnote reference '[^b]' inside a footnote definition body is silently dropped by pandoc (rendered as literal text)
--> example.qmd:3:11
|
3 | [^a]: See [^b].
| ^^^^
= help: footnotes do not nest in pandoc; inline the prose, restructure to keep the reference outside the definition body, or remove it
duplicate-reference-labels
Warns when reference links, footnotes, or cross-references reuse a label. Give each definition a unique label, and update any references to it.
Reference-link and footnote labels are also checked across files that are combined into one document, such as Quarto includes and bookdown chapters. Independently rendered Quarto documents may reuse those labels. Cross-reference labels, such as figure IDs, are checked across the project.
- Default
- On
- Auto-fix
- No
Diagnostic codes
| Code | Severity |
|---|---|
duplicate-reference-labels |
Warning |
Examples
[Read more][guide].
[guide]: /first
[guide]: /secondwarning: [duplicate-reference-labels] Duplicate reference label '[guide]' (first defined at line 3)
--> example.qmd:4:1
|
4 | [guide]: /second
| ^^^^^^^^^^^^^^^^
undefined-references
Warns about reference links, cross-references, and footnotes whose labels have no definition. Add the missing definition or correct the label. This includes shortcut links such as [guide] and collapsed links such as [guide][].
Cross-references with configured crossref-prefixes receive the same target validation as built-in prefixes. Targets must have a matching ID or executable chunk label in the document or project. Panache does not execute code or extensions to discover generated targets.
With citations enabled, a narrative citation’s suffix, such as [p. 4] in @author [p. 4], belongs to the citation and needs no reference definition. The suffix can follow the citation key on the next line in the same paragraph.
Labels include their inline markup: [<span>Guide</span>] does not match a definition named [Guide].
- Default
- On
- Auto-fix
- No
Diagnostic codes
| Code | Severity |
|---|---|
undefined-reference-label |
Warning |
undefined-footnote-id |
Warning |
undefined-reference-label
A reference-style link or cross-reference has no matching definition.
undefined-footnote-id
A footnote reference has no matching definition.
Examples
[Read more][missing].warning: [undefined-reference-label] Reference label '[missing]' not found
--> example.qmd:1:13
|
1 | [Read more][missing].
| ^^^^^^^
Text[^missing].warning: [undefined-footnote-id] Footnote '[^missing]' not found
--> example.qmd:1:5
|
1 | Text[^missing].
| ^^^^^^^^^^
With this configuration:
crossref-prefixes = ["qdr"]See @qdr-missing.warning: [undefined-reference-label] Cross-reference label '@qdr-missing' not found
--> example.qmd:1:6
|
1 | See @qdr-missing.
| ^^^^^^^^^^^
undefined-anchor
Warns about links such as [Methods](#methods) when the destination ID does not exist. Correct the link, add an explicit {#methods} ID, or link to an existing heading. IDs are case-sensitive.
The rule recognizes generated heading IDs, explicit attributes, code-cell labels, and supported HTML IDs. In Quarto and bookdown projects, it also checks anchors in other project documents and their includes.
Links to another file, full URLs, and bare # links are excluded. With citations enabled, #ref-key can resolve to a bibliography entry when the document cites that key.
- Default
- On
- Auto-fix
- No
Diagnostic codes
| Code | Severity |
|---|---|
undefined-anchor |
Warning |
Examples
[Methods](#methods)warning: [undefined-anchor] Anchor '#methods' not found in document
--> example.qmd:1:12
|
1 | [Methods](#methods)
| ^^^^^^^
unused-definitions
Warns about reference-link and footnote definitions that are never used. Remove an obsolete definition, or add the reference that was meant to use it.
During project linting, references in other project documents are included when checking whether a definition is used.
- Default
- On
- Auto-fix
- No
Diagnostic codes
| Code | Severity |
|---|---|
unused-definition-label |
Warning |
unused-footnote-id |
Warning |
unused-definition-label
A reference-link definition is never used.
unused-footnote-id
A footnote definition is never used.
Examples
[unused]: https://example.comwarning: [unused-definition-label] Reference definition '[unused]' is never used
--> example.qmd:1:1
|
1 | [unused]: https://example.com
| ^^^^^^^^
[^unused]: A note.warning: [unused-footnote-id] Footnote '[^unused]' is never used
--> example.qmd:1:1
|
1 | [^unused]: A note.
| ^^^^^^^^^
unspaced-citation
Warns when a known citation key touches the preceding word, as in See@smith2024. Pandoc treats that form as ordinary text.
Insert a space (See @smith2024) or use a bracketed citation (See[@smith2024]). The rule checks only keys found in a bibliography or inline references: entry, so ordinary email addresses are left alone. Escape a literal at sign as \@ if it should not introduce a citation.
- Default
- On
- Auto-fix
- No
- Requirements
-
extensions.citations = true.
Diagnostic codes
| Code | Severity |
|---|---|
unspaced-citation |
Warning |
Examples
---
references:
- id: smith2024
title: A study
---
See@smith2024.warning: [unspaced-citation] Citation '@smith2024' is glued to the preceding text and will not be recognized; separate it with a space or wrap it in brackets '[@smith2024]'
--> example.qmd:7:4
|
7 | See@smith2024.
| ^^^^^^^^^^
malformed-citation
Warns about incomplete citation markers, such as [@], [@ key], an empty @{}, or a missing closing bracket. Write a key immediately after @, and close every bracket or brace. Use @{...} for keys with unusual characters.
The rule skips code, math, escaped markers, email addresses, and working links. To check whether a complete key exists in the bibliography, use citation-keys.
- Default
- On
- Auto-fix
- No
- Requirements
-
extensions.citations = true.
Diagnostic codes
| Code | Severity |
|---|---|
malformed-citation |
Warning |
Examples
See [@].warning: [malformed-citation] Citation marker has no key; add a citation key after '@'
--> example.qmd:1:6
|
1 | See [@].
| ^
duplicate-yaml-anchor
Warns when a YAML document defines the same &name anchor more than once. An alias may then refer to a different value than you intended.
Rename the duplicate anchor and its aliases, or remove the extra definition. Anchors in separate frontmatter or code-cell option blocks are independent.
- Default
- On
- Auto-fix
- No
Diagnostic codes
| Code | Severity |
|---|---|
duplicate-yaml-anchor |
Warning |
Examples
---
first: &value 1
second: &value 2
---warning: [duplicate-yaml-anchor] YAML anchor `&value` is defined more than once
--> example.qmd:3:9
|
3 | second: &value 2
| ^^^^^^
unused-yaml-anchor
Warns about a YAML &name anchor with no matching *name alias in the same YAML document. Remove the anchor if it is no longer needed, or use an alias where you meant to reuse the value.
Aliases in another frontmatter or code-cell option block do not count as uses of the anchor.
- Default
- On
- Auto-fix
- No
Diagnostic codes
| Code | Severity |
|---|---|
unused-yaml-anchor |
Warning |
Examples
---
title: &title A report
---warning: [unused-yaml-anchor] YAML anchor `&title` is never used
--> example.qmd:2:8
|
2 | title: &title A report
| ^^^^^^
citation-keys
Checks cited keys against bibliography files and inline references: entries. It also reports files that cannot be read or parsed, duplicate bibliography keys, and duplicate inline reference IDs.
Check the file path and bibliography syntax first. Then correct missing keys or give conflicting entries distinct IDs.
- Default
- On
- Auto-fix
- No
- Requirements
-
extensions.citations = true.
Diagnostic codes
| Code | Severity |
|---|---|
bibliography-load-error |
Error |
bibliography-parse-error |
Error |
missing-bibliography-key |
Warning |
duplicate-bibliography-key |
Warning |
duplicate-inline-reference-id |
Warning |
bibliography-load-error
A bibliography file could not be read. Check that the path is correct and the file is accessible.
bibliography-parse-error
A bibliography file contains invalid syntax. Correct it using the syntax for its file format.
missing-bibliography-key
A cited key is absent from the loaded bibliography and inline references.
duplicate-bibliography-key
More than one bibliography entry uses the same key. Rename or remove the duplicate.
duplicate-inline-reference-id
An inline reference ID is repeated, or conflicts with a key in a bibliography file.
Examples
The declared bibliography file does not exist:
---
bibliography: missing.bib
---error: [bibliography-load-error] Failed to load bibliography missing.bib: File not found
--> example.qmd:2:15
|
2 | bibliography: missing.bib
| ^^^^^^^^^^^
The bibliography file cannot be parsed:
With refs.json:
not valid JSON---
bibliography: refs.json
---error: [bibliography-parse-error] Invalid bibliography entry: Invalid CSL-JSON: expected ident at line 1 column 2
--> example.qmd:1:1
|
1 | / ---
2 | | bibliography: refs.json
3 | | ---
| |____^
A citation has no matching entry:
With refs.bib:
@book{known, title = {A Book}}---
bibliography: refs.bib
---
See [@missing].warning: [missing-bibliography-key] Citation key 'missing' not found in bibliography
--> example.qmd:5:6
|
5 | See [@missing].
| ^^^^^^^^
Two bibliography entries share a key:
With refs.bib:
@book{same, title = {First}}
@book{same, title = {Second}}---
bibliography: refs.bib
---warning: [duplicate-bibliography-key] Duplicate bibliography key 'same' in refs.bib and refs.bib
--> example.qmd:2:15
|
2 | bibliography: refs.bib
| ^^^^^^^^
Two inline references share an ID:
---
references:
- id: same
title: First
- id: same
title: Second
---warning: [duplicate-inline-reference-id] Duplicate inline reference id 'same'
--> example.qmd:5:9
|
5 | - id: same
| ^^^^
citation-nonbreaking-space
Warns about a breakable space before a bracketed citation. Line wrapping can leave the citation at the start of a line, separated from the text it supports.
The fix replaces the gap with Pandoc’s nonbreaking space escape, \. If that escape is disabled, it inserts a nonbreaking space character instead. Citations at the start of a paragraph, after a hard line break, or already preceded by a nonbreaking space are left alone.
- Default
- On
- Auto-fix
- Available; see the examples for fix safety.
- Requirements
-
extensions.citations = true.
Diagnostic codes
| Code | Severity |
|---|---|
citation-nonbreaking-space |
Warning |
Examples
A result [@smith2024].warning: [citation-nonbreaking-space] Breakable space before citation; the rendered citation can be stranded at the start of a line
--> example.qmd:1:9
|
1 | A result [@smith2024].
| ^
= help: Replace with a non-breaking space (`\ `)
After panache lint --fix:
A result\ [@smith2024].crossref-as-link-target
Warns about link destinations beginning with @, such as [Figure 2](@fig-2). That creates a link to the literal URL @fig-2.
Use @fig-2 on its own for a cross-reference, or [Figure 2](#fig-2) for a link to an ID. The fix changes the destination’s leading @ to #.
- Default
- On
- Auto-fix
- Available; see the examples for fix safety.
- Requirements
-
extensions.citations = true.
Diagnostic codes
| Code | Severity |
|---|---|
crossref-as-link-target |
Warning |
Examples
# Results {#results}
[Results](@results)warning: [crossref-as-link-target] Link target starts with '@'; cross-references and citation keys must stand alone, not appear as a link destination
--> example.qmd:3:11
|
3 | [Results](@results)
| ^
= help: Replace '@' with '#' to link to an anchor
After panache lint --fix:
# Results {#results}
[Results](#results)chunk-label-spaces
Warns about spaces in executable code-cell labels. Labels such as several words can be difficult to reference reliably.
Use a label such as several-words or several_words, and update references to the cell.
- Default
- On
- Auto-fix
- No
- Requirements
-
extensions.fenced-code-attributes = true.
Diagnostic codes
| Code | Severity |
|---|---|
chunk-label-spaces |
Warning |
Examples
```{r several words}
1 + 1
```warning: [chunk-label-spaces] Chunk label 'several words' contains spaces and may break Quarto cross-references; use hyphens or underscores
--> example.qmd:1:7
|
1 | ```{r several words}
| ^^^^^^^^^^^^^
missing-chunk-labels
Warns about executable code cells with no label. Labels make cells easier to identify in errors and cross-references.
Add a label in the cell header or in a cell option, such as #| label: my-plot. Use the comment prefix for the cell’s language: #| for R or Python, //| for C++ or Rust, and --| for SQL.
- Default
- On
- Auto-fix
- No
- Requirements
- The Quarto or R Markdown flavor.
Diagnostic codes
| Code | Severity |
|---|---|
missing-chunk-labels |
Warning |
Examples
```{r}
1 + 1
```warning: [missing-chunk-labels] Executable code chunk has no label; add `#| label: ...`
--> example.qmd:1:4
|
1 | ```{r}
| ^^^
quarto-schema
Warns about YAML values that do not match Quarto’s expected type or allowed choices. It checks frontmatter, code-cell options, and project files such as _quarto.yml and _metadata.yml.
Use the expected type or one of the suggested values. Unknown keys are handled separately by quarto-schema-unknown-key.
Set validate-yaml: false in the affected document or manifest to skip schema checks when a filter needs a different form. YAML syntax errors are still reported. Some deeply nested options and restrictions tied to a particular output format are not checked.
- Default
- On
- Auto-fix
- No
- Requirements
- The Quarto flavor.
Diagnostic codes
| Code | Severity |
|---|---|
quarto-schema-type-mismatch |
Warning |
quarto-schema-invalid-enum |
Warning |
quarto-schema-type-mismatch
A value has the wrong type for the option, such as text where a boolean is required.
quarto-schema-invalid-enum
A value is not among the choices allowed for the option.
Examples
A boolean option has a text value:
---
toc: maybe
---warning: [quarto-schema-type-mismatch] value should be a boolean
--> example.qmd:2:6
|
2 | toc: maybe
| ^^^^^
An option has an unsupported value:
---
fig-align: sideways
---warning: [quarto-schema-invalid-enum] invalid value; expected one of: default, left, right, center
--> example.qmd:2:12
|
2 | fig-align: sideways
| ^^^^^^^^
quarto-schema-unknown-key
Warns about unknown or misspelled Quarto options in frontmatter, code-cell options, and project metadata. Check the suggested spelling or remove the unused option.
This rule is optional because Quarto allows custom metadata. At the top level, it warns only about names close to known options. Within sections that permit only predefined options, it reports any unknown key.
Like quarto-schema, it honors validate-yaml: false.
- Default
- Off
Enable this rule with [lint] extend-select = ["quarto-schema-unknown-key"].
- Auto-fix
- No
- Requirements
- The Quarto flavor.
Diagnostic codes
| Code | Severity |
|---|---|
quarto-schema-unknown-key |
Warning |
Examples
---
forrmat: html
---warning: [quarto-schema-unknown-key] unknown key `forrmat`; did you mean `format`?
--> example.qmd:2:1
|
2 | forrmat: html
| ^^^^^^^
figure-crossref-captions
Warns when a bookdown figure reference, such as \@ref(fig:plot), targets a code cell without a figure caption. A label alone does not create the figure that the reference needs.
Add a fig.cap or fig-cap option to the target cell, or correct the reference if it points to the wrong cell.
- Default
- On
- Auto-fix
- No
- Requirements
- The Quarto or R Markdown flavor.
Diagnostic codes
| Code | Severity |
|---|---|
figure-crossref-captions |
Warning |
Examples
This example uses the R Markdown flavor.
Figure \@ref(fig:plot).
```{r}
#| label: plot
plot(1:10)
```warning: [figure-crossref-captions] Figure cross-reference '@fig:plot' targets a chunk label without a figure caption (`fig-cap`/`fig.cap`)
--> example.Rmd:1:14
|
1 | Figure \@ref(fig:plot).
| ^^^^^^^^
unknown-emoji-alias
Warns about emoji shortcodes that Panache does not recognize, such as :not-a-real-emoji:. Check the shortcode’s spelling, use a supported alias, or insert the emoji character directly.
- Default
- On
- Auto-fix
- No
- Requirements
-
extensions.emoji = true.
Diagnostic codes
| Code | Severity |
|---|---|
unknown-emoji-alias |
Warning |
Examples
With this configuration:
[extensions]
emoji = trueHello :not-a-real-emoji:warning: [unknown-emoji-alias] Unknown emoji alias ':not-a-real-emoji:'
--> example.qmd:1:7
|
1 | Hello :not-a-real-emoji:
| ^^^^^^^^^^^^^^^^^^
html-entities
Warns about misspelled HTML named entities and missing semicolons, such as &ellips; or &numero. These may appear literally in rendered text instead of producing the intended character.
Correct the name and end it with a semicolon, or insert the character directly. The rule checks prose and skips code, math, raw HTML, and numeric references such as {.
- Default
- On
- Auto-fix
- No
Diagnostic codes
| Code | Severity |
|---|---|
html-entities |
Warning |
Examples
An ellipsis: &ellips;warning: [html-entities] Unknown HTML entity '&ellips;'
--> example.qmd:1:14
|
1 | An ellipsis: &ellips;
| ^^^^^^^^
= help: did you mean '…'?
html-unclosed-attribute
Warns about an HTML attribute value with an opening quote but no closing quote. A tag such as <a id="goal></a> may appear as ordinary text instead of creating a link or anchor.
Close the quote at the intended end of the value. Multiline values and unquoted attributes are allowed. The rule skips code, math, comments, and explicit raw HTML code spans or fences.
- Default
- On
- Auto-fix
- No
- Requirements
-
extensions.raw-html = true.
Diagnostic codes
| Code | Severity |
|---|---|
html-unclosed-attribute |
Warning |
Examples
<a id="goal></a>warning: [html-unclosed-attribute] Unclosed quoted value for HTML attribute 'id'
--> example.qmd:1:7
|
1 | <a id="goal></a>
| ^
= help: add the matching closing quote at the intended end of the value
link-text-is-url
Warns when a link’s visible text exactly repeats its destination URL. The fix replaces [https://example.com/](https://example.com/) with the shorter autolink <https://example.com/>.
Links with a title, formatted text, or any difference between the visible URL and destination are left alone. This includes differences in trailing slashes.
- Default
- On
- Auto-fix
- Available; see the examples for fix safety.
Diagnostic codes
| Code | Severity |
|---|---|
link-text-is-url |
Warning |
Examples
[https://example.com/](https://example.com/)warning: [link-text-is-url] Link text is identical to the URL; an autolink is shorter and clearer.
--> example.qmd:1:1
|
1 | [https://example.com/](https://example.com/)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: Convert to autolink
= help: rewrite as `<https://example.com/>`
After panache lint --fix:
<https://example.com/>stray-fenced-div-markers
Warns when ::: or a longer run of colons appears as paragraph text instead of opening or closing a fenced div. The colons may be misplaced, attached to another line, or missing an opening fence.
Put each fence on its own line and check that the opening fence has the intended class or attributes. Wrap literal mentions of ::: in backticks.
- Default
- On
- Auto-fix
- No
- Requirements
-
extensions.fenced-divs = true.
Diagnostic codes
| Code | Severity |
|---|---|
stray-fenced-div-markers |
Warning |
Examples
Text with a misplaced ::: marker.warning: [stray-fenced-div-markers] ':::' appears as text, not as a fenced div marker
--> example.qmd:1:23
|
1 | Text with a misplaced ::: marker.
| ^^^
= help: Pandoc only treats ':::' as a fenced div marker when it starts a line on its own (optionally followed by a class or attributes). Add a newline before it, or wrap it in backticks if it's intentional text
swallowed-list-marker
Warns when a line that looks like a list item is read as part of the preceding paragraph. Add a blank line before the list. If the marker is ordinary prose, escape it, as in \-.
Pandoc requires the blank line before a list. CommonMark and GFM allow bullets and lists starting at 1 to interrupt a paragraph, but a list starting at 2 still needs separation. The rule reports the first line in a consecutive run of affected items.
A paragraph with just one possible numbered marker, such as 10., stays quiet when the preceding line ends in a word or number and the text after the marker starts with a capital letter. This can be a number at the end of a wrapped sentence, as in increases by a factor followed by 10. The other runtimes. Single items after a colon or other punctuation still warn, as do paragraphs with multiple marker lines. Bullets and markers ending in ) also still warn.
- Default
- On
- Auto-fix
- No
Diagnostic codes
| Code | Severity |
|---|---|
swallowed-list-marker |
Warning |
Examples
Choose one option:
- First choice
- Second choicewarning: [swallowed-list-marker] '-' looks like a list marker, but the preceding line pulls it into a paragraph
--> example.qmd:2:1
|
2 | - First choice
| ^
= note: 2 consecutive lines here start with a list marker; all of them are reflowed into the paragraph above
= help: Pandoc-markdown never lets a list interrupt a paragraph. Insert a blank line above this line to start a real list, or escape the marker ('\-') if it is meant as prose
The wrapped sentence stays quiet. The numbered item after the colon still needs a blank line.
The runtime increases by roughly a factor
10. The other runtimes increase too.
Choose one option:
10. The only option.warning: [swallowed-list-marker] '10.' looks like a list marker, but the preceding line pulls it into a paragraph
--> example.qmd:5:1
|
5 | 10. The only option.
| ^^^
= help: Pandoc-markdown never lets a list interrupt a paragraph. Insert a blank line above this line to start a real list, or escape the marker ('10\.') if it is meant as prose
unspaced-list-marker
Warns about a line containing only -\ inside a list. The missing space means it remains part of the current item instead of starting a new item.
Add a space after - if you meant a new item, and supply its text. Remove the marker if you only meant to continue the existing item.
- Default
- On
- Auto-fix
- No
Diagnostic codes
| Code | Severity |
|---|---|
unspaced-list-marker |
Warning |
Examples
- First item
-\
- Second itemwarning: [unspaced-list-marker] Missing whitespace after '-': this line is paragraph text
--> example.qmd:2:3
|
2 | -\
| ^^
= help: If you intended a list item, add a space after '-' and check its indentation. Escape the hyphen as '\-' if it is literal text
table-column-count
Warns when a pipe table has more cells in a row than its separator row declares. Pandoc drops the extra cells when rendering the table.
Add the missing columns to the separator row, or remove the extra cells if they are unintended. Shorter rows are allowed because they are padded with empty cells.
- Default
- On
- Auto-fix
- No
Diagnostic codes
| Code | Severity |
|---|---|
table-column-count |
Warning |
Examples
| a | b | c |
|---|---|
| 1 | 2 | 3 |warning: [table-column-count] This row has 3 cells but the delimiter row declares 2 columns; the 1 extra cell is dropped when the table is rendered
--> example.qmd:1:11
|
1 | | a | b | c |
| ^
warning: [table-column-count] This row has 3 cells but the delimiter row declares 2 columns; the 1 extra cell is dropped when the table is rendered
--> example.qmd:3:11
|
3 | | 1 | 2 | 3 |
| ^
footnote-after-image
Warns when a footnote immediately follows a standalone image. Pandoc then treats the image and note as one paragraph, so the image loses its figure caption. Figure cross-references may also stop resolving.
Move the footnote inside the caption if it belongs there, or add a blank line between the image and the note to keep them separate. This check applies when extensions.implicit-figures is enabled.
- Default
- On
- Auto-fix
- No
- Requirements
-
extensions.footnotes = true.
Diagnostic codes
| Code | Severity |
|---|---|
footnote-after-image |
Warning |
Examples
{#fig-plot}
^[A note about the figure.]warning: [footnote-after-image] footnote attached to a standalone image keeps it from becoming a figure
--> example.qmd:2:1
|
2 | ^[A note about the figure.]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: an image becomes a figure only when it is alone in its paragraph; the trailing footnote demotes it
= note: the caption text will render as the image's alt attribute, not as a caption
= note: the id no longer labels a figure, so cross-references to it will not resolve
= help: move the footnote inside the caption, as in `![Caption. ^[note]](img.jpg)`, or separate it from the image with a blank line to keep the figure
footnote-swallowed-by-bracket
Warns when [ or ( directly follows an inline footnote’s closing bracket. Pandoc may read the note as a link label instead, leaving the footnote absent from the output.
The fix inserts a space after the note. For the ( form it requires --unsafe-fixes: confirm that you intended a footnote rather than a link preceded by a literal caret.
- Default
- On
- Auto-fix
- Available; see the examples for fix safety.
- Requirements
-
extensions.inline-footnotes = true.
Diagnostic codes
| Code | Severity |
|---|---|
footnote-swallowed-by-bracket |
Warning |
Examples
A reference link follows the apparent note:
Text^[A note][link].
[link]: https://example.comwarning: [footnote-swallowed-by-bracket] Inline footnote is followed directly by a bracket, so pandoc reads the label as a link instead and drops the footnote; insert a space after the closing `]`
--> example.qmd:1:5
|
1 | Text^[A note][link].
| ^^
= help: Insert a space after the inline footnote
After panache lint --fix:
Text^[A note] [link].
[link]: https://example.comA parenthesis follows the apparent note:
Text^[A note](https://example.com).warning: [footnote-swallowed-by-bracket] Inline footnote is followed directly by a bracket, so pandoc reads the label as a link instead and drops the footnote; insert a space after the closing `]`
--> example.qmd:1:5
|
1 | Text^[A note](https://example.com).
| ^^
= help: Insert a space after the inline footnote
After panache lint --fix --unsafe-fixes (review the change before applying it):
Text^[A note] (https://example.com).reversed-footnote-marker
Warns about [^...] containing prose where an inline footnote may have been intended. Inline footnotes start with ^[, as in ^[A note].
Confirm the intended meaning before applying the fix, which requires --unsafe-fixes. A valid but undefined label such as [^missing] belongs to undefined-references. Working links and cases where swapping the marker would still fail to create a footnote are left unfixed.
- Default
- On
- Auto-fix
- Available; see the examples for fix safety.
- Requirements
-
extensions.inline-footnotes = true.
Diagnostic codes
| Code | Severity |
|---|---|
reversed-footnote-marker |
Warning |
Examples
Text [^a longer explanation goes here].warning: [reversed-footnote-marker] Footnote label contains whitespace, so pandoc does not read `[^...]` as a footnote reference; write `^[...]` for an inline footnote
--> example.qmd:1:6
|
1 | Text [^a longer explanation goes here].
| ^^
= help: Swap `[^` for the inline-footnote opener `^[`
= help: the reference form `[^id]` takes a bare label and needs a matching `[^id]:` definition
After panache lint --fix --unsafe-fixes (review the change before applying it):
Text ^[a longer explanation goes here].space-before-punctuation
Warns about spaces or tabs before ., ,, and ; in paragraph text. The optional fix removes the gap.
Check the language and intended spacing before applying the fix with --unsafe-fixes. French documents retain spaces before semicolons. The document’s YAML lang setting takes precedence over [format].lang.
The rule skips code, math, headings, link text, and punctuation sequences such as . . .. The formatter preserves these spaces unless you apply a lint fix.
- Default
- On
- Auto-fix
- Available; see the examples for fix safety.
Diagnostic codes
| Code | Severity |
|---|---|
space-before-punctuation |
Warning |
Examples
We have A , and B ; so we have C .warning: [space-before-punctuation] Space before ',' may be unintended
--> example.qmd:1:10
|
1 | We have A , and B ; so we have C .
| ^^^
= help: Remove space before ','
warning: [space-before-punctuation] Space before ';' may be unintended
--> example.qmd:1:20
|
1 | We have A , and B ; so we have C .
| ^^^^
= help: Remove space before ';'
warning: [space-before-punctuation] Space before '.' may be unintended
--> example.qmd:1:38
|
1 | We have A , and B ; so we have C .
| ^^^^
= help: Remove space before '.'
After panache lint --fix --unsafe-fixes (review the change before applying it):
We have A, and B; so we have C.unsupported-metadata-key
Reports YAML frontmatter keys that Pandoc cannot use as metadata. Collection keys such as [a, b]: value and alias keys such as *name: value can prevent the document from rendering.
Replace the key with a normal name, or move the content out of the frontmatter if it was not meant to be metadata. Scalar keys such as 1 are accepted. Code-cell options are not checked by this rule.
- Default
- On
- Auto-fix
- No
- Requirements
- The Pandoc, Quarto, or R Markdown flavor.
Diagnostic codes
| Code | Severity |
|---|---|
unsupported-metadata-key |
Error |
Examples
---
[a, b]: value
---error: [unsupported-metadata-key] sequence used as a metadata key is not supported by pandoc
--> example.qmd:2:1
|
2 | [a, b]: value
| ^^^^^^
= note: pandoc converts frontmatter to metadata, where every key must be a string; it fails the whole document with `Non-string keys are not supported`
= help: quote the key to make it a string, or move the line out of the frontmatter if it was not meant to be metadata
YAML diagnostics
Panache emits YAML diagnostics when embedded YAML content is invalid. These apply to both document frontmatter (--- ... ---) and executable chunk hashpipe options (#| ...).
yaml-parse-error
- Severity
- Warning
- Auto-fix
- No
- Description
- The YAML contains invalid syntax, such as an unclosed quote or bracket. Correct the indicated syntax before checking other YAML settings.
Example (hashpipe):
```{r}
#| echo: [
1 + 1
```Diagnostic:
warning[yaml-parse-error]: YAML parse error: ...
--> document.qmd:2:10
yaml-structure-error
- Severity
- Warning
- Auto-fix
- No
- Description
-
The YAML is valid, but the document or code cell expects a mapping of option names to values. Check that each option uses the form
name: value.