denoland/deno · error · TypeError
${openContext} could not be iterated because iterator method
Error message
${openContext} could not be iterated because iterator method did not return object, but ${type(iter)}. What it means
WebIDL async-iterable conversion 'open' step: it calls the stored @@iterator/@@asyncIterator method on the value and requires the returned iterator to be an Object. If a primitive comes back, this TypeError includes the API context (openContext) and the actual type name from webidl's type() ('Undefined', 'String', 'Number', ...).
Source
Thrown at ext/webidl/00_webidl.js:1126
context,
);
}
sequenceType = "sync";
}
return {
// Fields used by extractBody / callers.
value: V,
object: V,
method,
type: sequenceType,
[AsyncSequence]: AsyncSequence,
// https://webidl.spec.whatwg.org/#async-sequence-open
open(openContext = context) {
// 1. Let iterator be ? GetIteratorFromMethod(object, method).
const iter = FunctionPrototypeCall(method, V);
if (type(iter) !== "Object") {
throw new TypeError(
`${openContext} could not be iterated because iterator method did not return object, but ${
type(iter)
}.`,
);
}
// 2. If type is "sync", set iterator to CreateAsyncFromSyncIterator(iterator).
const asyncIterator = sequenceType === "sync"
? createAsyncFromSyncIterator(iter)
: iter;
// Capture nextMethod per Iterator Record semantics.
const nextMethod = asyncIterator.next;
return {
// https://webidl.spec.whatwg.org/#async-iterator-get-next-value
// Exposed as an async iterator protocol shape for callers.
async next() {View on GitHub (pinned to f7822238ca)
Solutions
- Return an iterator object (usually this) from the @@iterator/@@asyncIterator method
- Or delegate: return source[Symbol.asyncIterator]();
- Pass a native iterable (Array, Map, Set, ReadableStream) instead of a custom object
Example fix
// before
const body = { [Symbol.asyncIterator]: () => 'not-an-iterator' };
await fetch(url, { body });
// after
const body = { async *[Symbol.asyncIterator]() { yield 'chunk'; } };
await fetch(url, { body }); Defensive patterns
Strategy: validation
Validate before calling
function assertOpenable(v: unknown) {
const m = (v as any)?.[Symbol.asyncIterator] ?? (v as any)?.[Symbol.iterator];
if (typeof m !== 'function') return; // absence is a different error
const iter = m.call(v);
if (typeof iter !== 'object' || iter === null) {
throw new TypeError('iterator method must return an iterator object');
}
} Type guard
const isAsyncIterable = (v: unknown): v is AsyncIterable<unknown> => v != null && typeof (v as Record<PropertyKey, unknown>)[Symbol.asyncIterator] === 'function';
Prevention
- The @@iterator/@@asyncIterator method must return an iterator (usually this), never the data
- Use async generators for fetch bodies
- Read the openContext in the message to find which argument failed
When it happens
Trigger: fetch(url, { body: { [Symbol.asyncIterator]: () => 'stream' } }) or any Deno API taking an async sequence where the iterator method returns a primitive instead of an iterator object.
Common situations: Writing [Symbol.asyncIterator]() { return this.items } where items is a string/number; async-iterator methods that return a value instead of this or an iterator; confusing 'the method returns the iterator' with 'the method returns the data'.
Related errors
- The iterator.next() method must return an object
- The iterator.return() method must return an object
- Cannot convert a BigInt value to a number
- Cannot convert a Symbol value to a string
- ${name} is not a function
AI-assisted analysis of denoland/deno@f7822238ca (2026-08-20).
Data as JSON: /api/errors/0ac4c41b6659b0f8.
Report an issue: GitHub.