denoland/deno · error · TypeError
${openContext} failed to close iterator because the return()
Error message
${openContext} failed to close iterator because the return() method did not return an object, but ${type(returnPromiseResult)}. What it means
When a WebIDL async-sequence consumer closes the iterator early (break, error, abort), it looks up the iterator's optional return(); if present, the awaited result must be an Object. Otherwise this TypeError is thrown, including the API context (openContext) and the offending type name.
Source
Thrown at ext/webidl/00_webidl.js:1183
opts,
);
return { done: false, value: iterValue };
},
// https://webidl.spec.whatwg.org/#async-iterator-close
async return(reason) {
const returnMethod = getMethod(asyncIterator, "return");
if (returnMethod === undefined) {
return undefined;
}
const returnPromiseResult = await FunctionPrototypeCall(
returnMethod,
asyncIterator,
reason,
);
if (type(returnPromiseResult) !== "Object") {
throw new TypeError(
`${openContext} failed to close iterator because the return() method did not return an object, but ${
type(returnPromiseResult)
}.`,
);
}
return undefined;
},
[SymbolAsyncIterator]() {
return this;
},
};
},
// Allow for-await-of over the converted async sequence directly.
[SymbolAsyncIterator]() {
return this.open(context);
},
};View on GitHub (pinned to f7822238ca)
Solutions
- Return { done: true } from return()
- Or omit return() - an absent method means no close is attempted
- When delegating, return the inner iterator's result object
Example fix
// before
async return() { await cleanup(); } // resolves to undefined
// after
async return() { await cleanup(); return { done: true }; } Defensive patterns
Strategy: validation
Type guard
interface CloseableAsyncIterator<T> extends AsyncIterator<T> {
return?(value?: any): Promise<IteratorResult<T>>;
}
// Typing return() as Promise<IteratorResult<T>> prevents resolving to primitives. Prevention
- return() must resolve to an object - conventionally { done: true }
- Test abort/cancel paths of custom async iterables
- When wrapping an inner iterator, return its result object from return()
When it happens
Trigger: An async-iterable fetch body whose return() resolves to a non-object - return() { } (undefined), async return() { await cleanup() } where cleanup returns a string, or return: async () => null - followed by early termination (AbortController, downstream error, read limit).
Common situations: Cleanup hooks that forget to return a value; returning a boolean success flag from return(); return() that resolves to a resource handle number.
Related errors
- ${name} is not a function
- The iterator.return() method must return an object
- ${openContext} failed to iterate next value because the next
- Cannot convert a BigInt value to a number
- Cannot convert a Symbol value to a string
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/421918e90b75f8fb.
Report an issue: GitHub.