denoland/deno · error · AnyError
Cannot use --watch with an npm package whose bin entry is a…
Error message
Cannot use --watch with an npm package whose bin entry is a native executable: {main_module} What it means
Deno's --watch mode restarts a JavaScript worker on file change, so the entrypoint must be JS/TS. When the main module resolves to an npm package whose `bin` entry is a native compiled executable (detected by is_npm_native_bin in cli/tools/run/mod.rs:327), watching is impossible: Deno cannot re-execute or reload a native binary through the runtime, so it refuses up front instead of silently not reloading.
Solutions
- Drop --watch and run the package directly: deno run npm:<pkg> or deno x <pkg> — both execute native bins fine.
- If you need restart-on-change, wrap it with an external watcher that re-invokes Deno: watchexec -r -- deno x <pkg>.
- If the package also ships a JS entry, point the main module at that file (npm:<pkg>/bin/js-entry.js) instead of the native bin.
Example fix
# before deno run --watch npm:@biomejs/biome check . # error: Cannot use --watch with an npm package whose bin entry is a native executable... # after — run directly, or let watchexec do the restarting deno x @biomejs/biome check . # or: watchexec -r --ext ts,js -- deno x @biomejs/biome check .
Defensive patterns
Strategy: validation
Validate before calling
# Before adding --watch, check what the package's bin actually is
pkg=node_modules/<pkg>
bin=$(node -p "(v => typeof v === 'string' ? v : Object.values(v)[0])(require('./' + process.argv[1] + '/package.json').bin)" "$pkg" 2>/dev/null)
file "$pkg/$bin" | grep -Eq 'ELF|Mach-O|PE32' && echo 'native bin: do NOT use --watch' || echo 'script: --watch ok' Prevention
- Reserve --watch for JS/TS entrypoints; native npm CLIs run fine without it.
- Check a package's bin target (file(1) output or its package.json) before wiring watch mode.
- Drop --watch on CI — one-shot runs gain nothing from it and it cannot work for native bins.
When it happens
Trigger: deno run --watch npm:<package> (or a watch-mode config whose main module is an npm specifier) where the package's `bin` target is a native ELF/Mach-O/PE binary, e.g. platform-specific CLIs shipped via per-OS optionalDependencies like esbuild, @biomejs/biome, or turbo.
Common situations: Porting a watch workflow from a local TS entrypoint to an npm CLI; CI scripts that reuse --watch flags mechanically; monorepos where the entry silently changes from a JS shim to a native bin after a package upgrade.
Related errors
- Could not resolve package req
- ' ' did not have a bin entry for
- ' ' did not have a bin property with a string or non-empty…
- is missing a prefix. Did you mean ` `?
- failed to deserialize npm process state
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/fb0d75546477ac19.
Report an issue: GitHub.
Appendix: source
Thrown at cli/tools/run/mod.rs:327
watcher_communicator.show_path_changed(changed_paths.clone());
Ok(async move {
let factory = CliFactory::from_flags_for_watcher(
flags,
watcher_communicator.clone(),
);
let cli_options = factory.cli_options()?;
let main_module = cli_options.resolve_main_module()?;
let preload_modules = cli_options.preload_modules()?;
let require_modules = cli_options.require_modules()?;
if main_module.scheme() == "npm" {
set_npm_user_agent();
}
maybe_npm_install(&factory).await?;
if is_npm_native_bin(&factory, main_module).await? {
return Err(deno_core::anyhow::anyhow!(
"Cannot use --watch with an npm package whose bin entry is a native executable: {main_module}"
));
}
let _ = watcher_communicator.watch_paths(cli_options.watch_paths());
let mut worker = factory
.create_cli_main_worker_factory()
.await?
.create_main_worker(
mode,
main_module.clone(),
preload_modules,
require_modules,
)
.await?;
let exit_code = if watch_flags.hmr {View on GitHub (pinned to 9ad36f7a2c)