{"record":{"id":"c0fd1f8790053cf0","repo":"karatelabs/karate","slug":"method-generator-prototype-called-on-incompatible-receiver","errorCode":null,"errorMessage":"Method Generator.prototype called on incompatible receiver","messagePattern":"Method Generator\\.prototype called on incompatible receiver","errorType":"exception","errorClass":"JsErrorException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsGeneratorPrototype.java","lineNumber":50,"sourceCode":"class JsGeneratorPrototype extends Prototype {\n\n    static final JsGeneratorPrototype INSTANCE = new JsGeneratorPrototype();\n\n    private JsGeneratorPrototype() {\n        super(JsObjectPrototype.INSTANCE);\n        install(\"next\", 1, this::next);\n        install(\"return\", 1, this::returnMethod);\n        install(\"throw\", 1, this::throwMethod);\n        // a generator is its own iterator\n        install(IterUtils.SYMBOL_ITERATOR, 0, (context, args) -> asGenerator(context));\n    }\n\n    private static JsGenerator asGenerator(Context context) {\n        Object thisObj = context.getThisObject();\n        if (thisObj instanceof JsGenerator g) {\n            return g;\n        }\n        throw JsErrorException.typeError(\"Method Generator.prototype called on incompatible receiver\");\n    }\n\n    private static Object arg(Object[] args) {\n        return args.length > 0 ? args[0] : Terms.UNDEFINED;\n    }\n\n    private Object next(Context context, Object[] args) {\n        return asGenerator(context).next((CoreContext) context, arg(args));\n    }\n\n    private Object returnMethod(Context context, Object[] args) {\n        return asGenerator(context).returnValue((CoreContext) context, arg(args));\n    }\n\n    private Object throwMethod(Context context, Object[] args) {\n        return asGenerator(context).throwValue((CoreContext) context, arg(args));\n    }\n","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsGeneratorPrototype.java#L32-L68","documentation":"A method from Generator.prototype (next, return, or throw) was invoked with a `this` that is not a JsGenerator. asGenerator narrows the receiver and throws a TypeError when the check fails, matching the spec's 'incompatible receiver' behavior for builtin prototype methods.","triggerScenarios":"Calling gen.next()/gen.return()/gen.throw() after the receiver was reassigned to a non-generator; detaching the method (e.g. `var n = gen.next; n()`) so `this` is undefined; passing a plain object that mimics a generator into code that calls its .next.","commonSituations":"Storing the next method as a callback without binding; wrapping generators in proxies/adapters that lose the receiver; iterating with a helper typed loosely that receives a non-generator value.","solutions":["Call the methods directly on the generator object: gen.next(), not a detached reference.","Bind detached methods: `const next = gen.next.bind(gen)`.","Guard with a check that the value is a generator before delegating.","Fix adapters/proxies so they forward method calls with the generator as receiver."],"exampleFix":"// before\nvar next = gen.next;\nnext(); // this is undefined\n// after\nvar next = gen.next.bind(gen);\nnext();","handlingStrategy":"type-guard","validationCode":"if (!gen || typeof gen.next !== 'function') { throw new Error('not a generator: ' + gen); }","typeGuard":"function isGenerator(v) { return v != null && typeof v.next === 'function' && typeof v[Symbol && Symbol.toStringTag || 'next'] !== 'undefined' && Object.prototype.toString.call(v) === '[object Generator]'; }","tryCatchPattern":"try { gen.next(v); } catch (e) { if (String(e).indexOf('incompatible receiver') !== -1) { karate.log('lost generator receiver'); } else { throw e; } }","preventionTips":["Do not detach generator methods without binding: use gen.next.bind(gen)","Forward calls with the generator as receiver in adapters/proxies","Validate the value is a generator before handing it to iteration helpers"],"tags":["javascript","generator","typeerror","receiver"],"backgroundTag":"type-mismatch","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"}