{"record":{"id":"1e1133c28d4defad","repo":"swc-project/swc","slug":"generator-is-already-executing","errorCode":null,"errorMessage":"Generator is already executing.","messagePattern":"Generator is already executing\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_transforms_base/src/helpers/generated/_ts_generator.rs","lineNumber":15,"sourceCode":"// This file is generated by `cargo codegen helpers`. DO NOT MODIFY.\n\nuse super::{HelperDef, HelperName};\n\npub const DEF: HelperDef = HelperDef {\n    name: HelperName::ts_generator,\n    local: \"_ts_generator\",\n    import_path: \"@swc/helpers/_/_ts_generator\",\n    #[cfg(feature = \"inline-helpers\")]\n    source: r#\"function _ts_generator(thisArg, body) {\n    var f, y, t, _ = { label: 0, sent: function () { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, g = Object.create((typeof Iterator === \"function\" ? Iterator : Object).prototype), d = Object.defineProperty;\n    return d(g, \"next\", { value: verb(0) }), d(g, \"throw\", { value: verb(1) }), d(g, \"return\", { value: verb(2) }), typeof Symbol === \"function\" && d(g, Symbol.iterator, { value: function () { return this; } }), g;\n    function verb(n) { return function (v) { return step([n, v]); }; }\n    function step(op) {\n        if (f) throw new TypeError(\"Generator is already executing.\");\n        while (g && (g = 0, op[0] && (_ = 0)), _) try {\n            if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\n            if (y = 0, t) op = [op[0] & 2, t.value];\n            switch (op[0]) {\n                case 0: case 1: t = op; break;\n                case 4: _.label++; return { value: op[1], done: false };\n                case 5: _.label++; y = op[1]; op = [0]; continue;\n                case 7: op = _.ops.pop(); _.trys.pop(); continue;\n                default:\n                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\n                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\n                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\n                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\n                    if (t[2]) _.ops.pop();\n                    _.trys.pop(); continue;\n            }\n            op = body.call(thisArg, _);\n        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_transforms_base/src/helpers/generated/_ts_generator.rs#L1-L33","documentation":"`_ts_generator` is the state-machine helper SWC emits when generators/async-generators are downleveled for old targets. It keeps an `f` (executing) flag; if `step()` is re-entered while a step is still in progress — i.e. the generator is advanced synchronously from inside its own running body — it throws `TypeError(\"Generator is already executing.\")` to protect its internal state.","triggerScenarios":"The generator body (or a function it calls synchronously) invokes `.next()`, `.throw()` or `.return()` on the same generator instance — self-driving generators, saga-style runners that resume a generator from a callback the generator itself invoked, or a scheduler that pumps the same instance recursively.","commonSituations":"Porting redux-saga/iterator-protocol code to a downleveled target where native generators tolerated the pattern; test harnesses that drive generators manually and accidentally re-enter; cooperative schedulers calling `it.next()` inside code the generator ran synchronously.","solutions":["Restructure so the generator is never advanced while it is executing: let the inner code return a request and let the outer driver resume the generator afterwards.","Queue re-entrant `next()` calls and drain the queue when the current step completes (see guard below).","Raise the compile target to ES2015+ so native generators (which define re-entrancy behavior differently) are emitted instead of the helper."],"exampleFix":"// before (downleveled generator)\nfunction* auto() {\n  schedule(() => it.next()); // re-enters while executing\n  yield 1;\n}\nconst it = auto();\nit.next(); // TypeError: Generator is already executing.\n\n// after\nfunction* auto() {\n  yield () => it.next(); // yield the continuation, driver resumes it\n  yield 1;\n}","handlingStrategy":"validation","validationCode":"// Wrap downleveled generators with a re-entrancy guard that queues instead of throwing.\nfunction guarded(gen) {\n  let executing = false;\n  const queue = [];\n  const pump = () => {\n    if (executing || queue.length === 0) return;\n    executing = true;\n    try { return queue.shift()(); }\n    finally { executing = false; setTimeout(pump, 0); }\n  };\n  const wrap = (method) => (arg) =>\n    new Promise((resolve, reject) => {\n      queue.push(() => { try { resolve(gen[method](arg)); } catch (e) { reject(e); } });\n      pump();\n    });\n  return { next: wrap('next'), throw: wrap('throw'), return: wrap('return'), [Symbol.iterator]() { return this; } };\n}","typeGuard":null,"tryCatchPattern":"try {\n  it.next();\n} catch (err) {\n  if (err instanceof TypeError && /already executing/.test(err.message)) {\n    // the generator re-entered itself — defer the resume to the next tick\n    queueMicrotask(() => it.next());\n  } else throw err;\n}","preventionTips":["Never advance a generator from code the generator itself called synchronously — yield a request instead and let the outer driver resume.","Prefer native generators (target ES2015+) when the runtime supports them, avoiding the helper's stricter re-entrancy behavior.","In saga/scheduler code, serialize `next()` calls for the same instance through a single pump function."],"tags":["generator","reentrancy","ts-generator","downlevel","state-machine"],"backgroundTag":"generator-reentrancy","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}