denoland/deno · error · Error
invalid doc test hashbang: #!/bin/sh (binary basename needs
Error message
invalid doc test hashbang: #!/bin/sh (binary basename needs to be 'deno')
What it means
With `deno test --doc`, every fenced code block in a doc comment becomes a generated Deno.test. If the fence starts with a shebang, parse_shebang() (cli/util/extract.rs:554) tokenizes it and searches the tokens for an executable whose file stem is exactly "deno". When none is found (e.g. #!/bin/sh), the extractor still emits the test but its body immediately throws Error("invalid doc test hashbang: ... (binary basename needs to be 'deno')") so the example fails loudly instead of silently running with the wrong permissions.
Source
Thrown at cli/util/extract.rs:2058
},
// Unparseable shebang fails the test, naming the reason.
Test {
input: Input {
source: r#"
/**
* ```ts
* #!/bin/sh
* foo();
* ```
*/
export function foo() {}
"#,
specifier: "file:///main.ts",
},
expected: vec![Expected {
source: r#"import { foo } from "file:///main.ts";
Deno.test("file:///main.ts#3-7.ts", async ()=>{
throw new Error("invalid doc test hashbang: #!/bin/sh (binary basename needs to be 'deno')");
foo();
});
"#,
specifier: "file:///main.ts#3-7.ts",
media_type: MediaType::TypeScript,
}],
},
// A scoped `--deny-*` can't be modelled, so the test is made to fail
// rather than run with broader permissions than the shebang declares.
Test {
input: Input {
source: r#"
/**
* ```ts
* #!/usr/bin/env -S deno run --allow-read --deny-read=/etc
* foo();
* ```
*/View on GitHub (pinned to 89f33cbef2)
Solutions
- Remove the shebang line from the fenced example - plain code needs none
- Change it to a shebang the parser recognizes, e.g. #!/usr/bin/env -S deno run --allow-read=. (the binary basename must be exactly 'deno', not 'deno-canary')
- Mark the fence to be skipped: ```ts ignore as the fence info string
Example fix
// before /** * ```ts * #!/bin/sh * foo(); * ``` */ // after /** * ```ts * foo(); * ``` */ // or keep the shebang example but skip it: ```ts ignore
Defensive patterns
Strategy: validation
Validate before calling
// CI check: find shebangs inside doc comments that do not target a 'deno' binary grep -rn --include='*.ts' -B2 '#!/bin/\(sh\|bash\)\|env node' src/ | grep -A2 '^.*\* ```' || true
Prevention
- Keep executable shebang examples out of ```ts doc fences; show them as ```sh instead
- If a doc example must show a script header, use #!/usr/bin/env -S deno run ...
- Mark non-runnable examples with ```ts ignore so deno test --doc skips them
When it happens
Trigger: An exported function's JSDoc contains a ```ts fence whose first line is #!/bin/sh, #!/bin/bash, or #!/usr/bin/env node, and the test suite runs with deno test --doc.
Common situations: Documenting CLI wrapper scripts or shell-invocable examples inside library doc comments; copy-pasting runnable examples from README files that carry sh shebangs; CI doc-test jobs that start failing after such an example is added.
Related errors
- invalid doc test hashbang: #!/usr/bin/env -S deno run --allo
- Bench failed because the "only" option was used
- Bench failed
- The bench name can't be empty
- Expected the second argument to assertSnapshot() to be an op
AI-assisted analysis of denoland/deno@89f33cbef2 (2026-08-16).
Data as JSON: /api/errors/43e6bfe64e13f725.
Report an issue: GitHub.