astral-sh/ruff · error · syn::Error

expected doc attribute to be in the form of #[doc = "..."]

Error message

expected doc attribute to be in the form of #[doc = "..."]

What it means

The rule-namespace derive macro parses a variant's `#[doc]` attribute expecting the literal form `#[doc = "..."]` (i.e. a name-value meta holding a string literal). If the doc attribute uses another meta form — such as a `///` comment expanded into `#[doc = ...]` with unexpected tokens, or a structured doc attribute — the macro aborts with this message at the doc attribute's span.

Source

Thrown at crates/ruff_macros/src/rule_namespace.rs:174

                match self { #url_match_arms }
            }
        }
    })
}

/// Parses an attribute in the form of `#[doc = " [name](https://example.com/)"]`
/// into a tuple of link label and URL.
fn parse_doc_attr(doc_attr: &Attribute) -> syn::Result<(String, String)> {
    let Meta::NameValue(MetaNameValue {
        value:
            syn::Expr::Lit(ExprLit {
                lit: Lit::Str(doc_lit),
                ..
            }),
        ..
    }) = &doc_attr.meta
    else {
        return Err(Error::new(
            doc_attr.span(),
            r#"expected doc attribute to be in the form of #[doc = "..."]"#,
        ));
    };
    parse_markdown_link(doc_lit.value().trim())
        .map(|(name, url)| (name.to_string(), url.to_string()))
        .ok_or_else(|| {
            Error::new(
                doc_lit.span(),
                "expected doc comment to be in the form of \
                `/// [name](https://example.com/)`",
            )
        })
}

fn parse_markdown_link(link: &str) -> Option<(&str, &str)> {
    link.strip_prefix('[')?.strip_suffix(')')?.split_once("](")
}

View on GitHub (pinned to 26f38c119c)

Solutions

  1. Write the doc comment as a plain string-literal doc: `/// [Name](https://url)` so it expands to `#[doc = "[Name](https://url)"]`.
  2. Remove any custom/structured `#[doc(...)]` attribute forms on the variant.
  3. Rebuild; if the error persists, inspect the exact attribute syntax on the reported span.

Example fix

// before
#[doc = 42]
MyLinter,
// after
/// [MyLinter](https://docs.example.com/mylinter)
#[prefix = "MYL"]
MyLinter,
Defensive patterns

Strategy: validation

Validate before calling

// Validate doc attribute shape before compiling:
// expect exactly: #[doc = "...string..."] i.e. plain /// comment, no #[doc(...)] structured form.

Prevention

When it happens

Trigger: A variant's doc attribute's meta does not match `Meta::NameValue` with a `Lit::Str` value. Raised in `parse_doc_attr` (rule_namespace.rs:174), called from `derive_impl` for each non-Ruff/Numpy variant.

Common situations: Writing `/// text` where text is not the expected link (this usually hits error 233 instead, but malformed attributes hit here); using `#[doc = ...]` with a non-string literal like `#[doc = 5]`; macro-generated doc attributes with unusual tokens.

Related errors


AI-assisted analysis of astral-sh/ruff@26f38c119c (2026-09-05). Data as JSON: /api/errors/c483ff40c7438973. Report an issue: GitHub.