denoland/deno · error · AnyError

'{}' did not have a bin entry for '{}'{}

Error message

'{}' did not have a bin entry for '{}'{}

What it means

The package.json has bin entries, but neither the explicitly requested name (from an `npm:<pkg>/<name>` selector) nor the default name (derived from the package name) matches any key in the bin map. The bail message appends a 'Possibilities:' list of the actual keys — rendered as `<pkg>` for the default key and `<pkg>/<key>` for the others — so the correct selector is printed right in the error.

Source

Thrown at libs/node_resolver/resolution.rs:2704

            prefix.push('@');
            prefix.push_str(version);
          }
          prefix
        })
        .unwrap_or_default();
      let keys = bins
        .keys()
        .map(|k| {
          if prefix.is_empty() {
            format!(" * {k}")
          } else if Some(k.as_str()) == default_bin {
            format!(" * {prefix}")
          } else {
            format!(" * {prefix}/{k}")
          }
        })
        .collect::<Vec<_>>();
      bail!(
        "'{}' did not have a bin entry for '{}'{}",
        package_json.path.display(),
        searching_bin.unwrap_or("<unspecified>"),
        if keys.is_empty() {
          "".to_string()
        } else {
          format!("\n\nPossibilities:\n{}", keys.join("\n"))
        }
      )
    }
  }
}

fn should_be_treated_as_relative_or_absolute_path(specifier: &str) -> bool {
  if specifier.is_empty() {
    return false;
  }

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Read the 'Possibilities:' lines in the error and use one of them: `deno run -A npm:<pkg>/<listed-key>` (for scoped packages the default entry is listed as the bare package name).
  2. Inspect available bins before running: `npm view <pkg> bin`.
  3. If a binary was renamed, update your script/alias to the new name, or pin the older version that shipped the name you use.
  4. For bare `npm:<pkg>` failures, run the explicit selector instead: `deno run -A npm:<pkg>/<actual-key>`.

Example fix

# before
$ deno run -A npm:@tools/toolbelt lint
# error: '...package.json' did not have a bin entry for 'lint'
# Possibilities:
#  * @tools/toolbelt
#  * @tools/toolbelt/tb-lint

# after: use a listed possibility
deno run -A npm:@tools/toolbelt/tb-lint
Defensive patterns

Strategy: validation

Validate before calling

// TypeScript/Deno: list the real bin keys before constructing a command
const res = await fetch(`https://registry.npmjs.org/${pkg}/latest`);
const pkgJson = await res.json();
console.log(Object.keys(pkgJson.bin ?? {})); // pick the selector from these keys

Type guard

function hasBinKey(
  p: { bin?: unknown; name?: string },
  key: string,
): boolean {
  if (typeof p.bin === "string") return p.name === key;
  return typeof p.bin === "object" && p.bin !== null && key in p.bin;
}

Try / catch

const { stderr, success } = await cmd.output();
if (!success && new TextDecoder().decode(stderr).includes("did not have a bin entry")) {
  // the stderr already lists Possibilities: re-run with npm:<pkg>/<listed-key>
}

Prevention

When it happens

Trigger: `deno run -A npm:<pkg>/<wrong-name>` where wrong-name is not a bin key; or bare `npm:<pkg>` when the bin keys do not include the package's own default name — typical for scoped packages (`@scope/pkg` whose only bin key is `pkg-cli`) and multi-binary packages.

Common situations: Scoped packages whose bin key drops the scope; binaries renamed between package versions while scripts keep the old name; multi-tool packages with several bin keys; guessing a bin name without checking package.json first.

Related errors


AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20). Data as JSON: /api/errors/448a721763684e2f. Report an issue: GitHub.