denoland/deno · error

{} is missing a prefix. Deno 3.0 requires `--` before script

Error message

{} is missing a prefix. Deno 3.0 requires `--` before script arguments in `deno install -g`. Did you mean `deno install -g {} -- {}`? Or maybe provide a `jsr:` or `npm:` prefix?

What it means

Deno 3.0 migration error for `deno install -g`. Before 3.0, script arguments could follow the module without a separator; now they must come after `--`. When the second positional is not a URL, not an existing local file, and no `--` args were given, Deno assumes you passed a pre-3.0-style script argument and tells you how to rewrite the command instead of silently treating the word as a package.

Source

Thrown at cli/tools/installer/global.rs:127

  // Validate every entry and default unprefixed bare package names to the npm
  // registry (matching `deno add` and local `deno install`) before installing
  // anything, so an error on entry N doesn't leave entries < N installed.
  let module_urls: Vec<String> = install_flags_global
    .module_urls
    .iter()
    .enumerate()
    .map(|(i, module_url)| -> Result<String, AnyError> {
      let entry_text = module_url;
      if cli_options.initial_cwd().join(entry_text).exists() {
        return Ok(module_url.clone());
      }
      // Migration error for users coming from Deno < 3.0 who passed script
      // args without `--`.
      if i == 1
        && install_flags_global.args.is_empty()
        && Url::parse(entry_text).is_err()
      {
        bail!(
          concat!(
            "{} is missing a prefix. Deno 3.0 requires `--` before script arguments in `deno install -g`. ",
            "Did you mean `deno install -g {} -- {}`? Or maybe provide a `jsr:` or `npm:` prefix?",
          ),
          entry_text,
          &install_flags_global.module_urls[0],
          install_flags_global.module_urls[1..].join(" "),
        );
      }
      if let Ok(Err(package_req)) =
        crate::tools::pm::AddRmPackageReq::parse(entry_text, None)
      {
        return Ok(format!("npm:{package_req}"));
      }
      Ok(module_url.clone())
    })
    .collect::<Result<_, _>>()?;

View on GitHub (pinned to a961cdec3b)

Solutions

  1. Insert `--` before script arguments: `deno install -g <module> -- 8000`
  2. If the second word is actually another package, give it a prefix: `deno install -g jsr:... npm:...`
  3. If it is a local file, run from the directory containing it (the existence check is relative to cwd)

Example fix

# before (Deno 2.x style)
deno install -g jsr:@std/http/file-server 8000

# after (Deno 3.x)
deno install -g jsr:@std/http/file-server -- 8000
Defensive patterns

Strategy: validation

Validate before calling

# reject pre-3.0 style before it runs (bash example):
# ensure every script arg comes after --
deno install -g jsr:@std/http/file-server -- 8000

Try / catch

Wrap global installs; on the 'missing a prefix / Deno 3.0 requires --' message, parse the suggested command from stderr and re-execute it verbatim.

Prevention

When it happens

Trigger: Conditions at cli/tools/installer/global.rs:127: exactly the 2nd module_url (i == 1), install_flags_global.args is empty (no `--` used), Url::parse fails on the entry (e.g. '8000'), and it is not an existing path relative to the initial cwd. Example: `deno install -g jsr:@std/http/file-server 8000`.

Common situations: Upgrading a project or docs/CI scripts from Deno 1.x/2.x to 3.x; muscle-memory invocations like `deno install -g file_server 8080` copied from old READMEs; install scripts in Dockerfiles that never used `--`.

Related errors


AI-assisted analysis of denoland/deno@a961cdec3b (2026-08-20). Data as JSON: /api/errors/3df9c9c52b7df9fb. Report an issue: GitHub.