{"id":"c7a1540c96bdc8fe","repo":"sindresorhus/is","slug":"expected-value-which-is-observable-received-val","errorCode":null,"errorMessage":"Expected value which is `Observable`, received value of type `${is(value)}`.","messagePattern":"Expected value which is `Observable`, received value of type `(.+?)`\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"source/index.ts","lineNumber":1824,"sourceCode":"\t}\n}\n\nexport function assertNumericString(value: unknown, message?: string): asserts value is `${number}` {\n\tif (!isNumericString(value)) {\n\t\tthrow new TypeError(message ?? typeErrorMessage('string with a number', value));\n\t}\n}\n\n// eslint-disable-next-line @typescript-eslint/no-restricted-types\nexport function assertObject(value: unknown, message?: string): asserts value is object {\n\tif (!isObject(value)) {\n\t\tthrow new TypeError(message ?? typeErrorMessage('Object', value));\n\t}\n}\n\nexport function assertObservable(value: unknown, message?: string): asserts value is ObservableLike {\n\tif (!isObservable(value)) {\n\t\tthrow new TypeError(message ?? typeErrorMessage('Observable', value));\n\t}\n}\n\nexport function assertOddInteger(value: number, message?: string): asserts value is number {\n\tif (!isOddInteger(value)) {\n\t\tthrow new TypeError(message ?? typeErrorMessage('odd integer', value));\n\t}\n}\n\nexport function assertPlainObject<Value = unknown>(value: unknown, message?: string): asserts value is Record<PropertyKey, Value> {\n\tif (!isPlainObject(value)) {\n\t\tthrow new TypeError(message ?? typeErrorMessage('plain object', value));\n\t}\n}\n\nexport function assertPositiveInteger(value: unknown, message?: string): asserts value is number {\n\tif (!isPositiveInteger(value)) {\n\t\tthrow new TypeError(message ?? typeErrorMessage('positive integer', value));","sourceCodeStart":1806,"sourceCodeEnd":1842,"githubUrl":"https://github.com/sindresorhus/is/blob/7821031c66cdeb7256a0feb2d506535f9e84fcaf/source/index.ts#L1806-L1842","documentation":"Thrown by `assert.observable()` when the value does not conform to the Observable contract — `isObservable` checks for the `Symbol.observable` (or `@@observable`) interop point per the TC39 Observable proposal. It narrows to `ObservableLike` so code can safely subscribe.","triggerScenarios":"Calling `assert.observable(value)` with a Promise, an RxJS Subject that lost its symbol through serialization, a plain object with only a `subscribe` method but no `Symbol.observable`, or an observable from a library/version that doesn't implement the interop symbol.","commonSituations":"Mixing RxJS versions in one dependency tree (two rxjs copies, each with its own symbol polyfill); passing a Promise where an Observable is expected; using a lightweight event-emitter that doesn't implement `Symbol.observable`; missing `symbol-observable` polyfill in older environments.","solutions":["Verify the value comes from a library implementing `Symbol.observable` (RxJS does); convert Promises with `from(promise)` (RxJS) first.","Deduplicate rxjs in your lockfile (`npm dedupe` / resolutions) so all code shares one Symbol.observable registration.","If the source only exposes `subscribe`, wrap it: `new Observable(sub => source.subscribe(sub))`.","Import `symbol-observable` polyfill early if targeting environments without the symbol."],"exampleFix":"// before\nassert.observable(somePromise); // throws: received 'Promise'\n// after\nimport {from} from 'rxjs';\nconst obs = from(somePromise);\nassert.observable(obs);","handlingStrategy":"type-guard","validationCode":"if (value == null || typeof value.subscribe !== 'function') {\n  throw new TypeError('Expected an Observable (object with subscribe and Symbol.observable)');\n}","typeGuard":"function isObservable(value: unknown): value is {subscribe: Function} {\n  return value != null &&\n    typeof (value as any).subscribe === 'function' &&\n    typeof (value as any)[Symbol.observable ?? '@@observable'] === 'function';\n}","tryCatchPattern":"try {\n  ow(value, ow.observable);\n} catch (error) {\n  if (error instanceof ArgumentError) {\n    throw new TypeError(`Expected an Observable stream: ${error.message}`);\n  }\n  throw error;\n}","preventionTips":["Don't pass a Promise where an Observable is expected — convert with rxjs from(promise)","Observable detection uses Symbol.observable — ensure your Observable implementation defines it (RxJS does)","Mixing RxJS versions or multiple rxjs copies can break interop; deduplicate the dependency","Wrap plain values with of(value) before passing to Observable-expecting APIs"],"tags":["type-check","assertion","observable","rxjs","interop"],"analyzedSha":"7821031c66cdeb7256a0feb2d506535f9e84fcaf","analyzedAt":"2026-07-31T18:34:06.268Z","schemaVersion":2}