{"record":{"id":"350219ce68a6a3e0","repo":"rust-lang/cargo","slug":"cannot-publish-with-open-namespaces","errorCode":null,"errorMessage":"cannot publish with `open-namespaces`","messagePattern":"cannot publish with `open-namespaces`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/workspace/parser/mod.rs","lineNumber":2994,"sourceCode":"\n/// Prepares the manifest for publishing.\n// - Path and git components of dependency specifications are removed.\n// - License path is updated to point within the package.\nfn prepare_toml_for_publish(\n    me: &manifest::TomlManifest,\n    ws: &Workspace<'_>,\n    package_root: &Path,\n    packaged_files: Option<&[PathBuf]>,\n) -> CargoResult<manifest::TomlManifest> {\n    let gctx = ws.gctx();\n\n    if me\n        .cargo_features\n        .iter()\n        .flat_map(|f| f.iter())\n        .any(|f| f == \"open-namespaces\")\n    {\n        anyhow::bail!(\"cannot publish with `open-namespaces`\")\n    }\n\n    let mut package = me.package().unwrap().clone();\n    package.workspace = None;\n    // Validates if build script file is included in package. If not, warn and ignore.\n    if let Some(custom_build_scripts) = package.normalized_build().expect(\"previously normalized\") {\n        let mut included_scripts = Vec::new();\n        for script in custom_build_scripts {\n            let path = Path::new(script).to_path_buf();\n            let included = packaged_files.map(|i| i.contains(&path)).unwrap_or(true);\n            if included {\n                let path = path\n                    .into_os_string()\n                    .into_string()\n                    .map_err(|_err| anyhow::format_err!(\"non-UTF8 `package.build`\"))?;\n                let path = normalize_path_string_sep(path);\n                included_scripts.push(path);\n            } else {","sourceCodeStart":2976,"sourceCodeEnd":3012,"githubUrl":"https://github.com/rust-lang/cargo/blob/98a09e7e7d62850f14e5b6132101fc1edd19a16f/src/workspace/parser/mod.rs#L2976-L3012","documentation":"Thrown by prepare_toml_for_publish when the manifest's cargo_features include 'open-namespaces'. The open-namespaces unstable feature relaxes package naming rules but is incompatible with registry publishing — published crate names must conform to the standard namespace rules. The check scans all cargo_features entries for an exact match.","triggerScenarios":"A manifest with cargo-feares = [\"open-namespaces\"] (or in [cargo_features]) that is being prepared for publish via prepare_for_publish / prepare_for_publish. The feature is detected in the flat-mapped feature list and the operation bails before producing the publishable manifest.","commonSituations":"A developer experiments with open-namespaces locally then runs `cargo publish` without removing the feature flag. A nightly-only workflow leaks into a publish pipeline. The feature was added for local testing and forgotten.","solutions":["Remove 'open-namespaces' from cargo-features in Cargo.toml before publishing.","Use a standard crate name that satisfies cargo's naming rules (alphanumeric, underscores, hyphens).","If you need the feature for development, gate it behind a non-published manifest or remove it in a publish pre-processing step."],"exampleFix":"# before\ncargo-features = [\"open-namespaces\"]\n\n[package]\nname = \"weird/name\"\n\n# after\n[package]\nname = \"weird-name\"","handlingStrategy":"validation","validationCode":"fn manifest_safe_for_publish(toml: &str) -> Result<(), String> {\n    if toml.contains(\"open-namespaces\") {\n        return Err(\"remove `open-namespaces` from cargo-features before publishing\".into());\n    }\n    Ok(())\n}","typeGuard":"fn publish_ready_features(toml: &toml::Value) -> bool {\n    toml.get(\"cargo_features\").and_then(|f| f.as_array())\n        .map(|arr| !arr.iter().any(|v| v.as_str() == Some(\"open-namespaces\")))\n        .unwrap_or(true)\n}","tryCatchPattern":null,"preventionTips":["Strip unstable cargo-features (especially open-namespaces) before `cargo publish`.","Run `cargo publish --dry-run` to catch publish-time rejections early.","Keep a separate publish-ready manifest if you need open-namespaces for local dev."],"tags":["cargo","publish","unstable","open-namespaces","registry"],"backgroundTag":null,"analyzedSha":"98a09e7e7d62850f14e5b6132101fc1edd19a16f","analyzedAt":"2026-08-11T17:42:36.556Z","contentChangedAt":"2026-08-11T17:42:36.556Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}