denoland/deno · error · anyhow::Error

Use 'deno run' to run a local file directly, 'deno x' is int

Error message

Use 'deno run' to run a local file directly, 'deno x' is intended for running commands from packages.

What it means

`deno x` executes commands from packages, not local files. If the command string looks file-like (starts with '.', '/', '~', or '\\', or has a file extension) and that path exists as a file on disk, deno refuses to run it and redirects to `deno run`.

Source

Thrown at cli/tools/x.rs:611

  }

  // When --package is specified, the command is the binary name and
  // the package flag specifies which package to install. Combine them
  // into a single specifier like "npm:package/binary" so the existing
  // resolution flow handles it correctly.
  let effective_command = if let Some(ref package) = command_flags.package {
    format!("{}/{}", package, command_flags.command)
  } else {
    command_flags.command.clone()
  };

  let is_file_like = effective_command.starts_with('.')
    || effective_command.starts_with('/')
    || effective_command.starts_with('~')
    || effective_command.starts_with('\\')
    || Path::new(&effective_command).extension().is_some();
  if is_file_like && Path::new(&effective_command).is_file() {
    return Err(anyhow::anyhow!(
      "Use 'deno run' to run a local file directly, 'deno x' is intended for running commands from packages."
    ));
  }

  let thing_to_run = match deno_core::url::Url::parse(&effective_command) {
    Ok(url) => {
      if url.scheme() == "npm" {
        let req_ref = NpmPackageReqReference::from_specifier(&url)?;
        ReqRefOrUrl::Npm(req_ref)
      } else if url.scheme() == "jsr" {
        let req_ref = JsrPackageReqReference::from_specifier(&url)?;
        ReqRefOrUrl::Jsr(req_ref)
      } else {
        ReqRefOrUrl::Url(url)
      }
    }
    Err(deno_core::url::ParseError::RelativeUrlWithoutBase) => {
      let new_command = format!("npm:{}", effective_command);

View on GitHub (pinned to 89f33cbef2)

Solutions

  1. Use `deno run` for local files (add permission flags as needed): `deno run ./script.ts`
  2. If a package command was intended, use explicit package syntax: `deno x npm:cowsay hello` or `deno x <pkg>/<bin>`
  3. For a local executable whose name contains a dot, rename it so the command is not file-like

Example fix

# before
deno x ./script.ts
# after
deno run --allow-all ./script.ts
Defensive patterns

Strategy: validation

Validate before calling

# bash: route file-like commands to deno run
cmd="$1"
if [[ "$cmd" == .* || "$cmd" == /* || "$cmd" == ~* || "$cmd" == *.* ]] && [ -f "$cmd" ]; then
  exec deno run "$@"
fi
exec deno x "$@"

Prevention

When it happens

Trigger: `deno x ./script.ts`, `deno x ~/tool.ts`, or `deno x main.ts` where the path exists as a file at launch time.

Common situations: Muscle memory from npx/bunx, which can execute local files; typos such as `deno x run mod.ts` where 'run mod.ts' is misread as one file-like token.

Related errors


AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16). Data as JSON: /api/errors/f7757883a9b40ec4. Report an issue: GitHub.