{"record":{"id":"6d998f853b0b980b","repo":"denoland/deno","slug":"invalid-doc-test-hashbang-usr-bin-env-s-deno","errorCode":null,"errorMessage":"invalid doc test hashbang: #!/usr/bin/env -S deno run --allow-read --deny-read=/etc (scoped --deny-* flags aren't supported yet, either remove them or ignore the test)","messagePattern":"invalid doc test hashbang: #!/usr/bin/env -S deno run --allow-read --deny-read=/etc \\(scoped --deny-\\* flags aren't supported yet, either remove them or ignore the test\\)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/util/extract.rs","lineNumber":2084,"sourceCode":"      // A scoped `--deny-*` can't be modelled, so the test is made to fail\n      // rather than run with broader permissions than the shebang declares.\n      Test {\n        input: Input {\n          source: r#\"\n/**\n * ```ts\n * #!/usr/bin/env -S deno run --allow-read --deny-read=/etc\n * foo();\n * ```\n */\nexport function foo() {}\n\"#,\n          specifier: \"file:///main.ts\",\n        },\n        expected: vec![Expected {\n          source: r#\"import { foo } from \"file:///main.ts\";\nDeno.test(\"file:///main.ts#3-7.ts\", async ()=>{\n    throw new Error(\"invalid doc test hashbang: #!/usr/bin/env -S deno run --allow-read --deny-read=/etc (scoped --deny-* flags aren't supported yet, either remove them or ignore the test)\");\n    foo();\n});\n\"#,\n          specifier: \"file:///main.ts#3-7.ts\",\n          media_type: MediaType::TypeScript,\n        }],\n      },\n      // A bare `--deny-*` becomes `false`; only the flags present in the\n      // shebang end up in the permissions object.\n      Test {\n        input: Input {\n          source: r#\"\n/**\n * ```ts\n * #!/usr/bin/env -S deno run --allow-read --deny-env\n * foo();\n * ```\n */","sourceCodeStart":2066,"sourceCodeEnd":2102,"githubUrl":"https://github.com/denoland/deno/blob/89f33cbef296a2b287f323d42de54c871fa69c77/cli/util/extract.rs#L2066-L2102","documentation":"Doc-test shebangs are parsed with Deno's own CLI flag parser and forwarded as the generated test's permission set. has_scoped_deny() (cli/util/extract.rs:588) reports true when any --deny-* flag carries a non-empty value list (deny_env/ffi/import/net/read/run/sys/write). Scoped denies like --deny-read=/etc cannot be expressed in the Deno.test permissions object, so the generated test throws this Error rather than running with broader permissions than the shebang declares.","triggerScenarios":"A ```ts doc-test fence starting with #!/usr/bin/env -S deno run --allow-read --deny-read=/etc (any --deny-<perm>=<value> form) executed under deno test --doc.","commonSituations":"Documenting hardened scripts that exclude sensitive paths via scoped deny flags; copying a real-world shebang from a script into its doc comment; hardening examples added during a security pass that then break doc tests.","solutions":["Remove the scoped --deny-*=... flag from the example's shebang","Use a whole-flag deny instead, e.g. bare --deny-read (no value), which maps to permissions: { read: false } and is supported","Mark the fence as ignored with ```ts ignore"],"exampleFix":"// before\n/**\n * ```ts\n * #!/usr/bin/env -S deno run --allow-read --deny-read=/etc\n * foo();\n * ```\n */\n\n// after\n/**\n * ```ts\n * #!/usr/bin/env -S deno run --allow-read --deny-read\n * foo();\n * ```\n */","handlingStrategy":"validation","validationCode":"// CI check: no scoped --deny-*=<value> flags in doc-test shebangs\ngrep -rn --include='*.ts' -- '--deny-[a-z]*=' src/ | grep '#!' || true","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use bare --deny-<perm> (no '=value') in documented shebangs","Remember scoped denies cannot be modelled in Deno.test permissions yet - do not copy hardened script shebangs verbatim into docs","Mark fences that need scoped denies with ```ts ignore"],"tags":["testing","doc-tests","cli","permissions"],"backgroundTag":null,"analyzedSha":"89f33cbef296a2b287f323d42de54c871fa69c77","analyzedAt":"2026-08-16T07:54:21.310Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}