rust-lang/cargo · error

` ` is unsupported as of the 2024 edition; instead use `…

Error message

`{old_path}` is unsupported as of the 2024 edition; instead use `{new_path}`
(in the `{name}` {kind})

What it means

Thrown by the deprecated_underscore helper when an old underscore-style field (e.g. dev_dependencies, build_dependencies, default_run) is present and the edition is 2024 or later. In earlier editions the underscore form is deprecated with a warning; in 2024 it is removed entirely and becomes a hard error. The message names the old path, the new hyphenated path, the field's owner (name), and its kind.

Solutions

  1. Rename the underscore field to its hyphenated form (dev_dependencies -> dev-dependencies, build_dependencies -> build-dependencies, default_run -> default-run).
  2. Run `cargo fix --edition` during the edition migration to auto-rename deprecated fields.
  3. Audit all Cargo.toml files in the workspace for underscore-style keys before bumping the edition.

Example fix

# before
[dev_dependencies]
serde = "1.0"
default_run = "my-bin"

# after
[dev-dependencies]
serde = "1.0"
default-run = "my-bin"
Defensive patterns

Strategy: validation

Validate before calling

const UNDERSCORE_FIELDS: &[&str] = &["dev_dependencies","build_dependencies","default_run"];
fn check_no_deprecated_underscores(toml: &str, edition: &str) -> Result<(), String> {
    if edition >= "2024" {
        for f in UNDERSCORE_FIELDS {
            if toml.contains(&format!("{f} =")) || toml.contains(&format!("[{f}]")) {
                return Err(format!("`{f}` is removed in edition 2024; use the hyphenated form"));
            }
        }
    }
    Ok(())
}

Type guard

fn manifest_uses_hyphen_fields(toml_text: &str) -> bool {
    !UNDERSCORE_FIELDS.iter().any(|f| toml_text.contains(f))
}

Prevention

When it happens

Trigger: A Cargo.toml with edition = "2024" that uses [dev-dependencies] spelled as dev_dependencies, or build_dependencies, or default_run in a target. deprecated_underscore is called for dev-dependencies, build-dependencies, and target fields during package/workspace parsing.

Common situations: Upgrading a crate to edition 2024 without renaming underscore fields to hyphenated equivalents. Old manifests predating hyphen normalization. Templates or generators emitting underscore keys.

Related errors


AI-assisted analysis of rust-lang/cargo@98a09e7e7d (2026-08-11). Data as JSON: /api/errors/224530a4f5b14235. Report an issue: GitHub.

Appendix: source

Thrown at src/workspace/parser/mod.rs:2895

    if let Err(err) = gctx.shell().print_report(&[group], true) {
        return err.into();
    }
    return AlreadyPrintedError::new(e.into()).into();
}

/// Warn about paths that have been deprecated and may conflict.
fn deprecated_underscore<T>(
    old: &Option<T>,
    new: &Option<T>,
    new_path: &str,
    name: &str,
    kind: &str,
    edition: Edition,
    warnings: &mut Vec<String>,
) -> CargoResult<()> {
    let old_path = new_path.replace("-", "_");
    if old.is_some() && Edition::Edition2024 <= edition {
        anyhow::bail!(
            "`{old_path}` is unsupported as of the 2024 edition; instead use `{new_path}`\n(in the `{name}` {kind})"
        );
    } else if old.is_some() && new.is_some() {
        warnings.push(format!(
            "`{old_path}` is redundant with `{new_path}`, preferring `{new_path}` in the `{name}` {kind}"
        ))
    } else if old.is_some() {
        warnings.push(format!(
            "`{old_path}` is deprecated in favor of `{new_path}` and will not work in the 2024 edition\n(in the `{name}` {kind})"
        ))
    }
    Ok(())
}

fn warn_on_unused(unused: &BTreeSet<String>, warnings: &mut Vec<String>) {
    use std::fmt::Write as _;

    for key in unused {

View on GitHub (pinned to 98a09e7e7d)