denoland/deno · error · AnyError

Lint watch on standard input is not supported.

Error message

Lint watch on standard input is not supported.

What it means

`deno lint --watch` re-lints files whenever they change, which requires watchable files on disk; standard input is a one-shot stream with nothing to watch. The lint entrypoint therefore rejects the combination up front instead of pretending to watch a stream that can never change.

Solutions

  1. Drop `--watch` when linting stdin: `cat mod.ts | deno lint -`
  2. Keep `--watch` but pass real paths: `deno lint --watch src/`
  3. Make the watch flag conditional in shared scripts — only add it when the arguments are files/dirs, not `-`

Example fix

# before
cat src/mod.ts | deno lint --watch -

# after
cat src/mod.ts | deno lint -   # one-shot stdin
deno lint --watch src/         # or watch real files
Defensive patterns

Strategy: validation

Validate before calling

const args = Deno.args;
if (args.includes('--watch') && (args.includes('-') || args.length === 0)) {
  throw new Error('deno lint: --watch cannot be combined with stdin input');
}

Type guard

const isStdinLint = (args: string[]): boolean =>
  args.includes('-') || args.every(a => a.startsWith('-'));

Prevention

When it happens

Trigger: Invoking lint with both watch mode and stdin input: `deno lint --watch -`, or `cat file.ts | deno lint --watch` — i.e. lint_flags.is_stdin() is true while flags.watch is set, at cli/tools/lint/mod.rs:87.

Common situations: CI pipelines that always pipe into `deno lint -` but copied a `--watch` flag from a dev script; editor tasks and git hooks configured with both; one shared lint invocation used for interactive and piped modes.

Related errors


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

Appendix: source

Thrown at cli/tools/lint/mod.rs:87

pub use linter::CliLinterOptions;
pub use plugins::PluginHostProxy;
pub use plugins::PluginLogger;
pub use plugins::create_runner_and_load_plugins;
pub use rules::ConfiguredRules;
pub use rules::LintRuleProvider;
pub use rules::collect_no_slow_type_diagnostics;

const JSON_SCHEMA_VERSION: u8 = 1;

static STDIN_FILE_NAME: &str = "$deno$stdin.mts";

pub async fn lint(
  flags: Arc<Flags>,
  lint_flags: LintFlags,
) -> Result<(), AnyError> {
  if flags.watch.is_some() {
    if lint_flags.is_stdin() {
      return Err(anyhow!("Lint watch on standard input is not supported.",));
    }

    return lint_with_watch(flags, lint_flags).await;
  }

  let factory = CliFactory::from_flags(flags);
  let cli_options = factory.cli_options()?;
  let lint_rule_provider = factory.lint_rule_provider().await?;
  let is_stdin = lint_flags.is_stdin();
  let compiler_options_resolver = factory.compiler_options_resolver()?;
  let workspace_lint_options =
    cli_options.resolve_workspace_lint_options(&lint_flags)?;
  let success = if is_stdin {
    lint_stdin(
      cli_options,
      lint_rule_provider,
      workspace_lint_options,
      lint_flags,

View on GitHub (pinned to 9ad36f7a2c)