rust-lang/cargo · error · anyhow::Error

`cargo init` cannot be run on existing Cargo packages help:

Error message

`cargo init` cannot be run on existing Cargo packages
help: use `cargo new` to create a package in a new subdirectory

What it means

The `init` command is for directories that do NOT yet have a Cargo.toml. If path.join("Cargo.toml").exists() at cargo_new.rs:516 is true, Cargo refuses (running init on an existing package would clobber/dupe the manifest). It points the user to `cargo new` to create a brand-new subdirectory package instead.

Source

Thrown at src/ops/cargo_new.rs:517

    let path = &opts.path;

    if let Some(home) = home_dir() {
        if path == &home {
            anyhow::bail!(
                "cannot create package in the home directory\n\n\
                 help: use `cargo init <path>` to create a package in a different directory"
            )
        }
    }
    let name = get_name(path, opts)?;
    let mut src_paths_types = vec![];
    detect_source_paths_and_types(path, name, &mut src_paths_types)?;
    let kind = calculate_new_project_kind(opts.kind, opts.auto_detect_kind, &src_paths_types);
    gctx.shell()
        .status("Creating", format!("{} package", opts.kind))?;

    if path.join("Cargo.toml").exists() {
        anyhow::bail!(
            "`cargo init` cannot be run on existing Cargo packages\n\
             help: use `cargo new` to create a package in a new subdirectory"
        )
    }
    check_path(path, &mut gctx.shell())?;

    let has_bin = kind.is_bin();

    if src_paths_types.is_empty() {
        src_paths_types.push(plan_new_source_file(has_bin));
    } else if src_paths_types.len() == 1 && !src_paths_types.iter().any(|x| x.bin == has_bin) {
        // we've found the only file and it's not the type user wants. Change the type and warn
        let file_type = if src_paths_types[0].bin {
            NewProjectKind::Bin
        } else {
            NewProjectKind::Lib
        };
        gctx.shell().warn(format!(

View on GitHub (pinned to 0e07a15537)

Solutions

  1. If you want a new crate, run `cargo new <subdir>` from inside the existing package
  2. If you genuinely want to wipe and re-init, delete Cargo.toml first (back it up!)
  3. Verify you are in the intended directory with `pwd` and `ls Cargo.toml`

Example fix

# before (Cargo.toml already present)
cargo init
# after
cargo new my-new-crate   # creates my-new-crate/ with its own manifest
Defensive patterns

Strategy: validation

Validate before calling

use std::path::Path;
fn ensure_no_manifest(dir: &Path) -> Result<(), String> {
    if dir.join("Cargo.toml").exists() {
        Err(format!("{dir:?} already has a Cargo.toml; use cargo new"))
    } else { Ok(()) }
}

ensure_no_manifest(path)?;

Type guard

import { existsSync } from 'fs';
import { join } from 'path';
function isFreshForInit(dir: string): boolean { return !existsSync(join(dir, 'Cargo.toml')); }

Prevention

When it happens

Trigger: `cargo init` inside a directory that already has a Cargo.toml (e.g. a workspace member, an old crate, a vendored dep). The check at cargo_new.rs:516 returns true.

Common situations: Wrong terminal tab (already inside a crate); running init in a monorepo root that has a workspace Cargo.toml; trying to 're-scaffold' an existing crate after deleting src/; IDE wizards that invoke init unconditionally.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/651201eee37e6b04.json. Report an issue: GitHub.