denoland/deno
Debugging
How to track down what Deno is doing — both in Rust and in the JS layer that ships inside the runtime.
Logging
Deno uses a per-module logger driven by the DENO_LOG environment variable:
# All modules at debug level
DENO_LOG=debug ./target/debug/deno run script.ts
# Specific modules
DENO_LOG=deno_core=debug,deno_runtime=trace ./target/debug/deno run script.ts
# Trace level for a specific area
DENO_LOG=deno_npm=trace,deno_resolver=trace ./target/debug/deno run script.tsLevels: error, warn, info, debug, trace. Many subsystems gate their detailed logging behind trace.
Backtraces
RUST_BACKTRACE=1 ./target/debug/deno run script.ts
RUST_BACKTRACE=full ./target/debug/deno run script.ts # include all framesFor panics during build use the same env var with cargo.
println / dbg!
In the Rust layer:
eprintln!("Debug: {value:?}");
dbg!(some_value);In the JS layer (ext/*/*.js, runtime/js/*.js, cli/js/*.js):
console.log('debug:', value);
console.error('debug:', value);JS console.log from inside the runtime layer goes to stderr by default (the console extension is in ext/console).
lldb / rust-gdb
Both work. With lldb:
lldb ./target/debug/deno
(lldb) run eval 'console.log("test")'
(lldb) breakpoint set -n mainFor breakpoints in async code, the function name is mangled — use breakpoint set -r <regex> or set on file:line. Symbol resolution is much better in debug builds (cargo build --bin deno).
Inspecting V8 internals
deno_core exposes V8 inspector hooks for the Chrome devtools protocol. Run:
./target/debug/deno run --inspect-brk script.tsThen connect Chrome devtools to the printed URL. The inspector server lives in libs/inspector_server.
For lower-level V8 flags pass them via DENO_V8_FLAGS:
DENO_V8_FLAGS=--print-bytecode ./target/debug/deno run script.tsPermission denials
When something fails with a permission error, the message indicates the category and resource. Re-run with -A (allow-all) to confirm it's just permissions, then narrow:
./target/debug/deno run -A script.ts
./target/debug/deno run --allow-read=./data --allow-net=api.example.com script.tsTo trace exactly which permission check fired, set DENO_LOG=deno_permissions=trace.
Module resolution issues
When import fails or resolves to the wrong file:
- Run
deno info <specifier>— this prints the resolved module graph including npm/jsr resolutions. DENO_LOG=deno_resolver=trace,deno_npm=trace,deno_graph=trace- Inspect the lockfile (
deno.lock) —libs/lockfilecontrols what gets pinned. Stale lockfile entries are a common source of "wrong version resolved" bugs. - For npm,
deno installandnode_modules/(if BYONM is on) interact. Toggle"nodeModulesDir": "auto"vs"manual"indeno.jsonto confirm.
Type checker issues
Deno can use either the bundled JS-based tsc (cli/tsc/) or tsgo (libs/typescript_go_client). To see what's happening:
DENO_LOG=deno=debug ./target/debug/deno check script.tsFor tsc-specific issues, the snapshot lives in cli/tsc/00_typescript.js. Updating it requires the steps in tools/update_typescript.md.
LSP debugging
The LSP runs on stdio when launched via deno lsp. Editor logs are usually the easiest entry point:
- VS Code: "Deno: Show Output" (Output panel → Deno Language Server)
- Add
"deno.internalDebug": trueto settings for verbose LSP traces. - Server-side, set
DENO_LOG=deno_lsp=trace.
For repro of an LSP bug, integration tests at tests/integration/lsp_tests.rs are the right home.
Snapshot mismatches
If you change extension JS and see "snapshot is stale" or runtime JS that doesn't match your edits, you're hitting a stale snapshot:
- Confirm by building with
--features hmr— if it works there, the snapshot is the issue. cargo clean -p deno && cargo build --bin denorebuilds the snapshot.runtime/snapshot.rsandcli/snapshot/are the relevant files.
Hangs and event loop issues
If deno run never exits, suspect either an open resource (timer, listener, request) or a stuck Tokio task:
Deno.unrefTimer(...)/ unref'ed listeners can keep the loop alive.- Add
console.logaround suspect async paths — output ordering tells you where it hangs. - For Rust-side hangs, attach lldb and
bt allto dump every thread.
Test-only debugging
For spec test failures:
cargo test specs::<area>::<test_name> -- --nocaptureto see stdout.- The test runner respects
DENO_LOG, soDENO_LOG=debug cargo test specs::<test>traces through. - Check the
.outfor[WILDCARD]placeholders that might be over- or under-greedy.
Troubleshooting checklist
| Symptom | First thing to try |
|---|---|
| Build fails on first run | Install cmake, protobuf, C/C++ toolchain; clone with --recurse-submodules |
| Test fails after pulling | cargo clean -p deno && cargo build --bin deno to refresh snapshots |
unwrap() panic in production binary |
RUST_BACKTRACE=full + check the file:line, replace with proper error |
npm: import resolves wrong version |
Check deno.lock, run deno install, try toggling nodeModulesDir |
| LSP misbehaves | Restart editor; check Deno output channel; reproduce with cargo test --test integration_tests lsp::... |
| Spec test passes locally, fails in CI | OS-specific path separator? Use [WILDCARD] for paths. Order-dependent? Use [UNORDERED_*]. |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.