{"record":{"id":"ff5c3aa41e1f75d4","repo":"ReactiveX/rxjs","slug":"iterator-must-define-a-callable-next-method","errorCode":null,"errorMessage":"Iterator must define a callable next() method","messagePattern":"Iterator must define a callable next\\(\\) method","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/observable-polyfill/src/index.ts","lineNumber":359,"sourceCode":"    throw new TypeError(`${String(key)} must be callable`);\n  }\n  return method as Callable;\n}\n\nfunction getSyncIteratorRecord<T>(value: object): SyncIteratorRecord<T> {\n  const iteratorMethod = getMethod(value, Symbol.iterator);\n  if (!iteratorMethod) {\n    throw new TypeError('Object does not define a callable Symbol.iterator method');\n  }\n\n  const iterator = iteratorMethod.call(value);\n  if (!isObject(iterator)) {\n    throw new TypeError('Symbol.iterator must return an object');\n  }\n\n  const next = getMethod(iterator, 'next');\n  if (!next) {\n    throw new TypeError('Iterator must define a callable next() method');\n  }\n  return { iterator, next };\n}\n\nfunction getAsyncIteratorRecord(value: object): AsyncIteratorRecord {\n  const asyncIteratorMethod = getMethod(value, Symbol.asyncIterator);\n  if (asyncIteratorMethod) {\n    const iterator = asyncIteratorMethod.call(value);\n    if (!isObject(iterator)) {\n      throw new TypeError('Symbol.asyncIterator must return an object');\n    }\n    return { iterator };\n  }\n\n  return { iterator: getSyncIteratorRecord(value).iterator };\n}\n\nfunction closeSyncIterator(record: SyncIteratorRecord<unknown>, reason: unknown): void {","sourceCodeStart":341,"sourceCodeEnd":377,"githubUrl":"https://github.com/ReactiveX/rxjs/blob/54796b38a57e6309f9861e174737479bb3f63f61/packages/observable-polyfill/src/index.ts#L341-L377","documentation":"This error is thrown by the iterator-record helper in @rxjs/observable-polyfill when converting a sync iterable (e.g. in Observable.from or fromIterable). After calling Symbol.iterator on the input, the returned iterator object must expose a callable next method; if getMethod(iterator, 'next') finds nothing (missing or non-function), the polyfill refuses to proceed per the observable-from-iterator protocol.","triggerScenarios":"Passing to Observable.from() an object whose Symbol.iterator returns an object without a next() method (or with next set to a non-function value). Also hit when getAsyncIteratorRecord falls back to the sync path for an object with no Symbol.asyncIterator whose Symbol.iterator is malformed.","commonSituations":"Custom iterable implementations that forget next(); objects that monkey-patch Symbol.iterator to return arbitrary state objects; arrays mutated to delete Array.prototype.next-like helpers; mocks/stubs in tests returning {} from [Symbol.iterator]().","solutions":["Fix the iterable so its [Symbol.iterator]() returns an iterator object with a callable next() method (e.g. delegate to an array or a generator function).","If wrapping another source, delegate: [Symbol.iterator]() { return someRealIterator; }","If you meant to pass a single value, wrap it: Observable.from([value]).","Validate the input before calling from() using typeof it[Symbol.iterator]?.().next === 'function'."],"exampleFix":"// before\nconst bad = { [Symbol.iterator]() { return {}; } };\nObservable.from(bad);\n// after\nconst good = { *[Symbol.iterator]() { yield 1; yield 2; } };\nObservable.from(good);","handlingStrategy":"validation","validationCode":"function isIterableObj(v: unknown): boolean {\n  if (!(v instanceof Object) || v === null) return false;\n  const it = (v as any)[Symbol.iterator]?.();\n  return it instanceof Object && typeof (it as any)?.next === 'function';\n}","typeGuard":"function isSyncIterable<T>(v: unknown): v is Iterable<T> {\n  return !!v && typeof v === 'object' &&\n    typeof (v as Iterable<T>)[Symbol.iterator] === 'function';\n}","tryCatchPattern":"try { obs = Observable.from(input); } catch (e) { if (e instanceof TypeError && /callable next/.test(e.message)) { /* fix or replace source */ } else throw e; }","preventionTips":["Always create iterables with generators or delegate to built-in iterables.","Validate unknown inputs with isSyncIterable before from().","Add subscribe-time tests for custom iterables."],"tags":["iterator","symbol-iterator","observable-from","typeerror","validation"],"backgroundTag":"invalid-iterator-protocol","analyzedSha":"54796b38a57e6309f9861e174737479bb3f63f61","analyzedAt":"2026-08-28T10:21:27.410Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}