denoland/deno · error · TypeError

Illegal constructor

Error message

Illegal constructor

What it means

ChildProcess has no public constructor; its constructor requires a private illegalConstructorKey symbol only Deno's internal spawn machinery possesses. Trying to construct it directly throws a TypeError. This is Deno's standard pattern for classes whose instances must come from a factory (here, Deno.Command.prototype.spawn()).

Source

Thrown at ext/process/40_process.js:482

  get stderr() {
    if (this.#stderr == null) {
      throw new TypeError("Cannot get 'stderr': 'stderr' is not piped");
    }
    return this.#stderr;
  }

  constructor(key = null, {
    signal,
    rid,
    pid,
    stdinRid,
    stdoutRid,
    stderrRid,
    ipcPipeRid, // internal
    extraPipeRids,
  } = null) {
    if (key !== illegalConstructorKey) {
      throw new TypeError("Illegal constructor");
    }

    this.#rid = rid;
    this.#pid = pid;
    this[_ipcPipeRid] = ipcPipeRid;
    this[_extraPipeRids] = extraPipeRids;
    this[_stdinRid] = stdinRid;
    this[_stdoutRid] = stdoutRid;
    this[_stderrRid] = stderrRid;

    if (stdinRid !== null) {
      this.#stdin = writableStreamForRid(stdinRid);
    }

    if (stdoutRid !== null) {
      this.#stdout = readableStreamForRidUnrefable(
        stdoutRid,
        ReadableStreamWithCollectors,

View on GitHub (pinned to 9ad36f7a2c)

Solutions

  1. Get instances only via new Deno.Command(cmd, opts).spawn()
  2. If you need a ChildProcess-like object in tests, create one from a real cheap command (e.g. Deno.execPath() with args: ["eval", ""]) instead of constructing the class
  3. For type annotations, import the type from Deno's built-in typings (Deno.ChildProcess) rather than instantiating

Example fix

// before
const child = new ChildProcess({ rid: 3, pid: 42 }); // TypeError: Illegal constructor

// after
const child = new Deno.Command(Deno.execPath(), { args: ["eval", ""], stdout: "piped" }).spawn();
Defensive patterns

Strategy: validation

Validate before calling

const child = new Deno.Command(cmd, { stdout: "piped" }).spawn(); // the only sanctioned factory

Prevention

When it happens

Trigger: Executing new ChildProcess(...) in user code (ChildProcess is not even exported on the Deno namespace), or passing deserialized/forged constructor arguments to build one manually.

Common situations: Copying internal source into user code; attempting to subclass or mock ChildProcess with new; confusing the class with process.nextTick-style globals while writing test doubles.

Related errors


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