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, or info
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-fixes alongside --fix to 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

### Results
warning: [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

## Results

empty-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 item
warning: [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]: /second
warning: [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.com
warning: [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].

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 = true
Hello :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 &#123;.

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 '&hellip;'?

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

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 choice
warning: [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 item
warning: [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

![A caption.](image.png){#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.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][link].
  |     ^^
  = help: Insert a space after the inline footnote

After panache lint --fix:

Text^[A note] [link].

[link]: https://example.com

A 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.