{"record":{"id":"b5887780115d9370","repo":"sveltejs/svelte","slug":"value-is-not-async-iterable","errorCode":null,"errorMessage":"value is not async iterable","messagePattern":"value is not async iterable","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/svelte/src/internal/client/reactivity/async.js","lineNumber":233,"sourceCode":" * after the `async_iterator` return resolves (if it runs)\n * @template T\n * @template TReturn\n * @param {Iterable<T> | AsyncIterable<T>} iterable\n * @returns {AsyncGenerator<T, TReturn | undefined>}\n */\nexport async function* for_await_track_reactivity_loss(iterable) {\n\t// This is based on the algorithms described in ECMA-262:\n\t// ForIn/OfBodyEvaluation\n\t// https://tc39.es/ecma262/multipage/ecmascript-language-statements-and-declarations.html#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset\n\t// AsyncIteratorClose\n\t// https://tc39.es/ecma262/multipage/abstract-operations.html#sec-asynciteratorclose\n\n\t/** @type {AsyncIterator<T, TReturn>} */\n\t// @ts-ignore\n\tconst iterator = iterable[Symbol.asyncIterator]?.() ?? iterable[Symbol.iterator]?.();\n\n\tif (iterator === undefined) {\n\t\tthrow new TypeError('value is not async iterable');\n\t}\n\n\t// eslint-disable-next-line no-useless-assignment\n\tlet invoke_return = true;\n\n\ttry {\n\t\twhile (true) {\n\t\t\tconst { done, value } = (await track_reactivity_loss(iterator.next()))();\n\t\t\tif (done) {\n\t\t\t\tinvoke_return = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tvar prev = reactivity_loss_tracker;\n\t\t\ttry {\n\t\t\t\tyield value;\n\t\t\t} catch (e) {\n\t\t\t\tset_reactivity_loss_tracker(prev);\n\t\t\t\t// If the yield throws, we need to call `return` but not return its value, instead rethrow","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/sveltejs/svelte/blob/20b341f10048cf1016a2028ac7eee5595cfef6a5/packages/svelte/src/internal/client/reactivity/async.js#L215-L251","documentation":"In DEV, Svelte wraps `for await` loops with `for_await_track_reactivity_loss` to warn when reactivity is lost across async boundaries. This TypeError is thrown when the value handed to a `for await...of` loop is neither async-iterable (no `Symbol.asyncIterator`) nor sync-iterable (no `Symbol.iterator`) — both probes return `undefined`. It mirrors native JS `for await` semantics but surfaces inside Svelte's reactivity-tracking layer.","triggerScenarios":"A `for await (const x of expr)` loop where `expr` is a non-iterable value: a raw `fetch` `Response` (instead of `response.body`), `null`, a number, or a plain object. The function probes `iterable[Symbol.asyncIterator]` then `iterable[Symbol.iterator]`; if both yield `undefined`, it throws.","commonSituations":"Iterating a `fetch` Response directly instead of `.body`; awaiting a value that resolves to a non-iterable; returning a plain object from an async function and looping over it; DEV-mode only (production throws the native TypeError).","solutions":["Iterate a true async iterable: a ReadableStream's `.body`, an async generator, or an array (which has `Symbol.iterator`).","Guard against null/undefined with a default: `for await (const x of data ?? [])`.","For `fetch`, iterate `response.body` (async-iterable in modern runtimes), not the `Response` object."],"exampleFix":"// before\nasync function load() {\n\tfor await (const chunk of res) { /* res is a Response, not iterable */ }\n}\n// after\nasync function load() {\n\tfor await (const chunk of res.body) { /* ReadableStream is async iterable */ }\n}","handlingStrategy":"validation","validationCode":"function isAsyncIterable(v) {\n\treturn v != null && (typeof v[Symbol.asyncIterator] === 'function' || typeof v[Symbol.iterator] === 'function');\n}\nif (!isAsyncIterable(data)) throw new Error('Expected an async iterable');\nfor await (const x of data) { /* ... */ }","typeGuard":"function isAsyncIterable(v) {\n\treturn v != null && (typeof v[Symbol.asyncIterator] === 'function' || typeof v[Symbol.iterator] === 'function');\n}","tryCatchPattern":null,"preventionTips":["Validate iterables before `for await`.","Default to empty arrays with `?? []`.","Iterate `response.body`, not the `Response` object.","Remember this DEV wrapper adds reactivity-loss tracking on top of native semantics."],"tags":["async","iterable","reactivity","runtime","dev-only"],"backgroundTag":null,"analyzedSha":"20b341f10048cf1016a2028ac7eee5595cfef6a5","analyzedAt":"2026-08-12T23:37:30.399Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}