loco-rs/loco · error
: : ` ` needs a reason — write it as ```rust ="why this is…
Error message
{}:{}: `{SKIP_MARKER}` needs a reason — write it as ```rust {SKIP_MARKER}="why this is not Rust" What it means
The docs-syntax checker supports opting a Rust block out of checking by annotating the fence with a skip marker; this bail fires when the marker is present but carries no reason. The tool requires the reason attribute so that every opt-out is documented and auditable.
Solutions
- Change the fence to ```` ```rust skip="<reason>" ```` with a non-empty quoted reason
- Alternatively remove the skip marker entirely if the block is valid Rust and should be checked
Example fix
// before ```rust skip let x = "not compilable"; ``` // after ```rust skip="illustrative pseudo-code, not compilable" let x = "not compilable"; ```
Defensive patterns
Strategy: validation
Validate before calling
grep -rnE '^```rust\s+skip\s*$' docs/ && echo 'skip markers missing reasons'
Prevention
- Always write skip="reason" when opting a block out
- Lint docs/ for bare skip markers in CI
When it happens
Trigger: Writing ```` ```rust skip ```` (or with an empty/unparseable reason) in a docs markdown file, causing `reason_at` to return `None` when `collect` processes the file.
Common situations: Adding a skip marker in a hurry while fixing CI; copying an old-style marker without a quoted reason; forgetting the `="reason"` attribute.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- found no ```rust blocks under
- found no ```rust blocks in
- : : ```rust block is never closed
- does not exist
AI-assisted analysis of loco-rs/loco@23639d1e36 (2026-09-12).
Data as JSON: /api/errors/b70d0a9657e4eb58.
Report an issue: GitHub.
Appendix: source
Thrown at xtask/src/docs_syntax.rs:190
"rs" => doc_comments_only(&fs::read_to_string(&path)?),
_ => continue,
};
let lines: Vec<&str> = contents.lines().collect();
let mut index = 0;
while index < lines.len() {
if !fence.is_match(lines[index]) {
index += 1;
continue;
}
let opened_at = index;
// A bare `no-syntax-check` with no reason is rejected rather than
// honoured — see the module docs.
let skipped = match lines[opened_at].find(SKIP_MARKER) {
None => false,
Some(at) => {
let reason = reason_at(&lines[opened_at][at + SKIP_MARKER.len()..]);
if reason.is_none() {
bail!(
"{}:{}: `{SKIP_MARKER}` needs a reason — write it as \
```rust {SKIP_MARKER}=\"why this is not Rust\"",
path.display(),
opened_at + 1
);
}
true
}
};
index += 1;
let start = index;
while index < lines.len() && !closing.is_match(lines[index]) {
index += 1;
}
if index >= lines.len() {
bail!(
"{}:{}: ```rust block is never closed",
path.display(),View on GitHub (pinned to 23639d1e36)