Skip to content

fromStream() tokenizers do not close the underlying Node.js Readable #1289

@sindresorhus

Description

@sindresorhus

I found that strtok3.fromStream() tokenizers do not actually close the underlying Node.js Readable when tokenizer.close() is called.

Root cause:

  • lib/core.js wires fromStream() through StreamReader
  • lib/stream/StreamReader.js implements:
    • abort() as only this.reject(new AbortError())
    • close() as only return this.abort()
  • Neither path calls stream.destroy()

So tokenizer.close() only aborts pending tokenizer reads. It does not tear down the source stream itself.

Why this matters:

A consumer can successfully detect enough bytes, call await tokenizer.close(), and still leave the original Readable and socket alive in the background. For HTTP responses, that means the body keeps downloading after the caller is done with detection.

I reproduced this with file-type, which correctly calls await tokenizer.close() in a finally block. Without a local workaround, a Node IncomingMessage stays open after detection completes.

Expected behavior:

await tokenizer.close() for tokenizers created from Node streams should close or destroy the underlying Readable, so consumers do not need package-specific teardown workarounds after successful detection.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions