no-floating-web-stream-locks
Require Web Stream readers and writers to be retained so their locks can be released.
Rule catalog ID: R019
Targeted pattern scopeโ
This type-aware rule targets lock-producing Web Streams methods:
ReadableStream#getReader()WritableStream#getWriter()
The rule uses TypeScript parser services to confirm that the receiver is a Web
ReadableStream or WritableStream. That avoids flagging project-local
objects that happen to expose methods named getReader() or getWriter().
What this rule reportsโ
The rule reports:
- discarded stream readers
- discarded stream writers
- immediately chained reader or writer use where the reader/writer handle is lost
Immediate releaseLock() calls are allowed. The rule focuses on cases where the
lock owner is unavailable to cleanup code.
Why this rule existsโ
getReader() and getWriter() lock the stream to the returned reader or writer.
The lock should be released with releaseLock() when the owner is done with the
stream. If the reader or writer is discarded, later cleanup code cannot release
that lock.
Incorrectโ
new ReadableStream<Uint8Array>().getReader();
stream.getReader().read();
stream.getWriter().write(chunk);
Correctโ
const reader = stream.getReader();
try {
await reader.read();
} finally {
reader.releaseLock();
}
function createReader(stream: ReadableStream<Uint8Array>) {
return stream.getReader();
}
streamReaderRegistry.add(stream.getReader());
Behavior and migration notesโ
This rule is type-aware and requires parser services. Enable it through a
type-checked preset or configure parserOptions.projectService yourself.
This rule does not autofix. Rewriting stream.getReader().read() into a
retained reader requires a surrounding try/finally cleanup shape, which is
too context-dependent for a safe automatic fix.
ESLint flat config exampleโ
import runtimeCleanup from "eslint-plugin-runtime-cleanup";
export default [
runtimeCleanup.configs["recommended-type-checked"],
];
When not to use itโ
Do not enable this rule in JavaScript-only projects without TypeScript parser services. For code that intentionally locks a stream for the entire process lifetime, use a narrow disable comment and document that ownership boundary.