{"record":{"id":"6dd2be052399d1fd","repo":"rust-lang/cargo","slug":"cannot-open-specified-crate-s-documentation-no-do","errorCode":null,"errorMessage":"cannot open specified crate's documentation: no documentation generated","messagePattern":"cannot open specified crate's documentation: no documentation generated","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/ops/cargo_doc.rs","lineNumber":68,"sourceCode":"    pub open_result: bool,\n    /// Same as `rustdoc --output-format`\n    pub output_format: OutputFormat,\n    /// Options to pass through to the compiler\n    pub compile_opts: ops::CompileOptions,\n}\n\n/// Main method for `cargo doc`.\npub fn doc(ws: &Workspace<'_>, options: &DocOptions) -> CargoResult<()> {\n    let compilation = ops::compile(ws, &options.compile_opts)?;\n\n    let wants_json_doc = matches!(options.output_format, OutputFormat::Json);\n    if ws.gctx().cli_unstable().rustdoc_mergeable_info && !wants_json_doc {\n        merge_cross_crate_info(ws, &compilation)?;\n    }\n\n    if options.open_result {\n        let name = &compilation.root_crate_names.get(0).ok_or_else(|| {\n            anyhow::anyhow!(\n                \"cannot open specified crate's documentation: no documentation generated\"\n            )\n        })?;\n        let kind = options.compile_opts.build_config.single_requested_kind()?;\n\n        let path = path_by_output_format(&compilation, &kind, &name, &options.output_format);\n\n        if path.exists() {\n            util::open::open(&path, ws.gctx())?;\n        }\n    } else if ws.gctx().shell().verbosity() == Verbosity::Verbose {\n        for name in &compilation.root_crate_names {\n            for kind in &options.compile_opts.build_config.requested_kinds {\n                let path =\n                    path_by_output_format(&compilation, &kind, &name, &options.output_format);\n                if path.exists() {\n                    let mut shell = ws.gctx().shell();\n                    let link = shell.err_file_hyperlink(&path);","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/rust-lang/cargo/blob/eb98b54bc9f3c74519f43d066cb3fd02ebc88df0/src/ops/cargo_doc.rs#L50-L86","documentation":"Thrown by `cargo doc --open` when the compilation produced zero root crate names, meaning there is no documentation file to open in a browser. `root_crate_names` is empty when no root-level crate (lib/bin) was documented — e.g. the package has no doc-able root target, all targets were filtered out, or only dependencies were compiled. Because `--open` needs a concrete path to launch, cargo refuses rather than guessing.","triggerScenarios":"Running `cargo doc --open` (or `--open` with any output format) on a package/selection that yields no root crate to document: a package with only `[[bin]]` targets that are all excluded, a doc-build where `root_crate_names` came back empty (e.g. `cargo doc -p <dep-only-crate>` with no members), or `cargo doc --no-deps` on a virtual manifest workspace with no selected member.","commonSituations":"Running `cargo doc --open` from a workspace root with `-p` pointing at a dependency instead of a member. Pointing `--open` at a crate whose lib target has `doc = false`. A virtual workspace (`[workspace]` only, no `[package]`) with no package selector. After deleting `src/lib.rs` but keeping `--open` in a script.","solutions":["Drop `--open` when you only need docs generated without auto-launching: `cargo doc`.","Select a real member that has a doc-able root crate: `cargo doc --open -p <member-with-lib>`.","Ensure the target you want documented has `doc = true` (default) and is not excluded via `--exclude` or target-level `doc = false`.","For virtual workspaces, run `cargo doc --open` from inside a member directory or pass an explicit `-p <member>`.","If you scripted `--open`, guard it: only pass `--open` when at least one root crate is expected."],"exampleFix":"# before\n$ cargo doc --open -p some-dependency   # error: no documentation generated\n\n# after\n$ cargo doc -p some-dependency           # just builds, no open\n$ cargo doc --open -p my-workspace-member  # opens the member's docs","handlingStrategy":"validation","validationCode":"// Before calling `cargo doc --open` programmatically, check that a root crate will be produced.\nfn should_open(has_doc_root: bool, want_open: bool) -> bool { want_open && has_doc_root }\n// Determine has_doc_root from `cargo metadata` (members with a lib/bin target where doc != false).","typeGuard":"fn has_docable_root(targets: &[TargetInfo]) -> bool {\n    targets.iter().any(|t| (t.is_lib || t.is_bin) && t.doc_enabled)\n}","tryCatchPattern":null,"preventionTips":["Only pass `--open` when you know a root crate will be documented (e.g. a member with a lib target).","For scripted doc generation, omit `--open` and open the path yourself after confirming it exists.","In virtual workspaces, always select a member with `-p` before `--open`.","Avoid `--open` when documenting a dependency-only selection."],"tags":["doc","cargo-doc","cli-usage","open"],"backgroundTag":null,"analyzedSha":"eb98b54bc9f3c74519f43d066cb3fd02ebc88df0","analyzedAt":"2026-08-11T17:42:36.556Z","contentChangedAt":"2026-08-11T17:42:36.556Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}