{"record":{"id":"addd4a4be5021c71","repo":"karatelabs/karate","slug":"generator-is-already-running-jsgenerator","errorCode":null,"errorMessage":"Generator is already running","messagePattern":"Generator is already running","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsGenerator.java","lineNumber":64,"sourceCode":"\n    static JsObject result(Object value, boolean done) {\n        JsObject r = new JsObject();\n        r.putMember(\"value\", value);\n        r.putMember(\"done\", done);\n        return r;\n    }\n\n    Object next(CoreContext ctx, Object value) {\n        if (activation.isDone()) {\n            return result(Terms.UNDEFINED, true);\n        }\n        return drive(ctx, ResumeKind.NEXT, value);\n    }\n\n    Object returnValue(CoreContext ctx, Object value) {\n        if (activation.isDone() || !activation.isStarted()) {\n            if (activation.isRunning()) {\n                throw JsErrorException.typeError(\"Generator is already running\");\n            }\n            activation.retire(); // NOT_STARTED: no body code runs\n            return result(value, true);\n        }\n        return drive(ctx, ResumeKind.RETURN, value);\n    }\n\n    Object throwValue(CoreContext ctx, Object value) {\n        if (activation.isDone() || !activation.isStarted()) {\n            if (activation.isRunning()) {\n                throw JsErrorException.typeError(\"Generator is already running\");\n            }\n            activation.retire(); // NOT_STARTED: no body code runs\n            ctx.stopAndThrow(value);\n            return Terms.UNDEFINED;\n        }\n        return drive(ctx, ResumeKind.THROW, value);\n    }","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsGenerator.java#L46-L82","documentation":"generator.return(value) was called while the generator's activation is currently executing (running). Per the generator protocol a generator cannot be resumed from within its own frame, so the engine throws a TypeError instead of corrupting the activation stack. This is surfaced by JsGenerator.returnValue when isDone/isStarted checks pass but the activation is marked running.","triggerScenarios":"Calling gen.return(x) from inside the generator's own body (e.g. via a callback or helper the generator invokes), or re-entering the generator recursively through a function that closes over it.","commonSituations":"Generator body delegates to a callback that calls gen.return() to 'finish early'; recursive iteration helpers; async-like code that tries to finalize a generator from a listener it started.","solutions":["Move the gen.return(...) call outside the generator body, after the driving loop completes.","Use a flag/queue so the inner code signals completion instead of calling return() directly.","If the body should stop, throw or return from inside the body rather than calling gen.return() on itself.","Review with a call-flow check whether any closure invoked by the generator retains the generator reference."],"exampleFix":"// before (inside generator body invoked callback)\nonDone: () => gen.return(result)\n// after: signal via flag, call return() outside\nonDone: () => finished = true;\n// ...later, outside the generator frame:\nif (finished) gen.return(result);","handlingStrategy":"try-catch","validationCode":"// no caller-side pre-check exists for running state; avoid re-entrant gen.return() by design","typeGuard":null,"tryCatchPattern":"try { gen.return(v); } catch (e) { if (String(e).indexOf('already running') !== -1) { pendingReturn = v; } else { throw e; } }","preventionTips":["Never call gen.return()/gen.throw() from callbacks invoked by the generator body","Use flags or queues to signal completion across the generator boundary","Keep generator driving code in one place (a single loop/driver)"],"tags":["javascript","generator","reentrancy","typeerror"],"backgroundTag":"invalid-state-transition","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}