{"record":{"id":"2ac516ad9894c704","repo":"astral-sh/ruff","slug":"expected-doc-comment-to-be-in-the-form-of-na","errorCode":null,"errorMessage":"expected doc comment to be in the form of `/// [name](https://example.com/)`","messagePattern":"expected doc comment to be in the form of `/// \\[name\\]\\(https://example\\.com/\\)`","errorType":"exception","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/ruff_macros/src/rule_namespace.rs","lineNumber":182,"sourceCode":"fn parse_doc_attr(doc_attr: &Attribute) -> syn::Result<(String, String)> {\n    let Meta::NameValue(MetaNameValue {\n        value:\n            syn::Expr::Lit(ExprLit {\n                lit: Lit::Str(doc_lit),\n                ..\n            }),\n        ..\n    }) = &doc_attr.meta\n    else {\n        return Err(Error::new(\n            doc_attr.span(),\n            r#\"expected doc attribute to be in the form of #[doc = \"...\"]\"#,\n        ));\n    };\n    parse_markdown_link(doc_lit.value().trim())\n        .map(|(name, url)| (name.to_string(), url.to_string()))\n        .ok_or_else(|| {\n            Error::new(\n                doc_lit.span(),\n                \"expected doc comment to be in the form of \\\n                `/// [name](https://example.com/)`\",\n            )\n        })\n}\n\nfn parse_markdown_link(link: &str) -> Option<(&str, &str)> {\n    link.strip_prefix('[')?.strip_suffix(')')?.split_once(\"](\")\n}\n\nenum ParseStrategy {\n    SinglePrefix,\n    MultiplePrefixes,\n}\n","sourceCodeStart":164,"sourceCodeEnd":198,"githubUrl":"https://github.com/astral-sh/ruff/blob/26f38c119cac42e4d320ba08f09224fdec74af2c/crates/ruff_macros/src/rule_namespace.rs#L164-L198","documentation":"The rule-namespace derive macro requires each linter variant's doc comment to be a markdown link of the exact form `[name](url)`, from which it extracts the linter's display name and documentation URL. `parse_doc_attr` returns this error when the doc string exists and is well-formed as an attribute but its content does not parse as a markdown link.","triggerScenarios":"A variant's doc comment contains free text instead of a link, e.g. `/// My linter docs`, or a malformed link like `[name](not-a-url)`. Raised in `parse_doc_attr` (rule_namespace.rs:182) when `parse_markdown_link` returns None.","commonSituations":"Contributing a new linter and writing a descriptive comment instead of the required link; editing the doc comment for readability and breaking the `[text](https://...)` shape; using a relative URL instead of an absolute https URL.","solutions":["Rewrite the doc comment as `/// [Display Name](https://absolute-url)` with an https URL.","Verify there is no extra prose before or after the link inside the doc comment.","Rebuild to confirm the name/URL pair now parses."],"exampleFix":"// before\n/// Lints f-strings usage.\n#[prefix = \"MYL\"]\nMyLinter,\n// after\n/// [MyLinter](https://docs.example.com/mylinter)\n#[prefix = \"MYL\"]\nMyLinter,","handlingStrategy":"validation","validationCode":"// Validate locally that the doc comment parses as a markdown link:\n// /^(\\[[^\\]]+\\])\\((https?:\\/\\/[^\\s)]+)\\)$/ matching the trimmed doc text.","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Template: `/// [Display Name](https://docs.astral.sh/ruff/...)` — copy from a neighboring variant.","No prose around the link inside the doc comment.","Use absolute https URLs."],"tags":["proc-macro","compile-time","rust","markdown"],"backgroundTag":"invalid-doc-comment-format","analyzedSha":"26f38c119cac42e4d320ba08f09224fdec74af2c","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}