{"record":{"id":"bc775a89ea3a75a6","repo":"awslabs/llrt","slug":"illegal-constructor","errorCode":null,"errorMessage":"Illegal constructor","messagePattern":"Illegal constructor","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"modules/llrt_stream_web/src/readable/default_controller.rs","lineNumber":624,"sourceCode":"        let promise_primordials = objects.stream.promise_primordials.clone();\n        let objects_class = objects.into_inner();\n\n        Ok((\n            cancel_algorithm.call(ctx, &promise_primordials, reason)?,\n            objects_class,\n        ))\n    }\n}\n\n#[methods(rename_all = \"camelCase\")]\nimpl<'js> ReadableStreamDefaultController<'js> {\n    // this is required by web platform tests for unclear reasons\n    fn constructor() -> Self {\n        unimplemented!()\n    }\n\n    #[qjs(constructor)]\n    fn new(ctx: Ctx<'js>) -> Result<Class<'js, Self>> {\n        Err(Exception::throw_type(&ctx, \"Illegal constructor\"))\n    }\n\n    // readonly attribute unrestricted double? desiredSize;\n    #[qjs(get)]\n    fn desired_size(&self) -> Null<f64> {\n        let stream = OwnedBorrow::from_class(self.stream.clone());\n        self.readable_stream_default_controller_get_desired_size(&stream)\n    }\n\n    // undefined close();\n    fn close(ctx: Ctx<'js>, controller: This<OwnedBorrowMut<'js, Self>>) -> Result<()> {\n        let objects = ReadableStreamObjects::from_default_controller(controller.0);\n\n        // If ! ReadableStreamDefaultControllerCanCloseOrEnqueue(this) is false, throw a TypeError exception.\n        if !objects\n            .controller\n            .readable_stream_default_controller_can_close_or_enqueue(&objects.stream)","sourceCodeStart":606,"sourceCodeEnd":642,"githubUrl":"https://github.com/awslabs/llrt/blob/742fc00b82cbeaab1c1b76f0d706c302a5cbc306/modules/llrt_stream_web/src/readable/default_controller.rs#L606-L642","documentation":"ReadableStreamDefaultController's JS-exposed constructor deliberately throws a TypeError('Illegal constructor'). Per the WHATWG streams spec, ReadableStreamDefaultController cannot be constructed directly by user code — it is created internally by ReadableStream. The #[qjs(constructor)] binding exists so attempts fail with this spec-mandated message rather than a runtime crash.","triggerScenarios":"Executing `new ReadableStreamDefaultController(...)` in JS — the only way to trigger it; legitimate use is always indirect via `new ReadableStream({ ... })`.","commonSituations":"Code ported from Node's internal-stream usage or web-platform-test-style code that instantiates controllers directly; misunderstanding that the controller is an internal slot of ReadableStream, not a public class.","solutions":["Do not construct the controller directly; use `new ReadableStream({ start, pull, cancel })` and access it via the stream's internal controller.","If you need custom behavior, implement it in the underlying source algorithms rather than subclassing the controller.","For tests, obtain the controller from a ReadableStream instance instead of new-ing one."],"exampleFix":"// before\nconst controller = new ReadableStreamDefaultController(); // throws\n// after\nconst stream = new ReadableStream({\n  start(c) {\n    c.enqueue('data'); // c is the default controller\n  }\n});","handlingStrategy":"try-catch","validationCode":"if (ctor === ReadableStreamDefaultController) throw new TypeError('Illegal constructor: use new ReadableStream() instead');","typeGuard":null,"tryCatchPattern":"try {\n  const c = new ReadableStreamDefaultController();\n} catch (e) {\n  if (e instanceof TypeError && e.message === 'Illegal constructor') {\n    stream = new ReadableStream({ start(c) { /* controller available here */ } });\n  } else throw e;\n}","preventionTips":["Never instantiate ReadableStreamDefaultController/ByteLengthQueuingBuffer-style internal classes directly.","Access the controller through the ReadableStream underlying-source callbacks.","Run web platform tests to catch spec-incompatible stream usage early."],"tags":["streams","web-api","constructor","spec"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"742fc00b82cbeaab1c1b76f0d706c302a5cbc306","analyzedAt":"2026-09-12T11:14:07.838Z","contentChangedAt":"2026-09-12T11:14:07.838Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}