{"record":{"id":"982ee36a35f39aa6","repo":"ReactiveX/rxjs","slug":"string-value-is-not-observable","errorCode":null,"errorMessage":"${String(value)} is not observable","messagePattern":"(.+?) is not observable","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/observable-polyfill/src/index.ts","lineNumber":550,"sourceCode":"            subscriber.error(error);\n          }\n        },\n        (error) => subscriber.error(error)\n      );\n    };\n\n    pull();\n  });\n}\n\nclass ObservableImpl<T> implements Subscribable<T> {\n  static from<T>(value: ObservableValue<T>): Observable<T> {\n    if (value instanceof Observable) {\n      return value;\n    }\n\n    if (!isObject(value)) {\n      throw new TypeError(`${String(value)} is not observable`);\n    }\n\n    const ObservableCtor = staticCtor<T>(this);\n    const asyncIteratorMethod = getMethod(value, Symbol.asyncIterator);\n    if (asyncIteratorMethod) {\n      return fromAsyncIterable(ObservableCtor, value);\n    }\n\n    const iteratorMethod = getMethod(value, Symbol.iterator);\n    if (iteratorMethod) {\n      return fromIterable(ObservableCtor, value);\n    }\n\n    const thenMethod = getMethod(value, 'then');\n    if (thenMethod) {\n      return new ObservableCtor((subscriber) => {\n        Promise.resolve(value as PromiseLike<T>).then(\n          (output) => {","sourceCodeStart":532,"sourceCodeEnd":568,"githubUrl":"https://github.com/ReactiveX/rxjs/blob/54796b38a57e6309f9861e174737479bb3f63f61/packages/observable-polyfill/src/index.ts#L532-L568","documentation":"Observable.from() first rejects non-objects with this TypeError: only objects (or Observable instances) can be converted. Primitives like numbers, strings, undefined, or symbols fail immediately because none of the conversion paths (asyncIterable, iterable, Observable-like with Symbol.observable, thenable/promise) can apply.","triggerScenarios":"Observable.from(42), Observable.from('hello'), Observable.from(null), Observable.from(undefined) — any primitive argument.","commonSituations":"Passing a value that was expected to be an Observable or Promise but is actually undefined due to an import/export mistake or bad destructuring; dynamically-typed data where a field is sometimes a primitive; porting code from a library whose from() accepted single values.","solutions":["If you want the value as a single emission, wrap it in an array: Observable.from([value]) — or use an of-style creation.","Check that the variable is actually defined at the call site (undefined from a failed import or typo).","If it should be a Promise, use Observable.from(Promise.resolve(value)).","Add a type guard before calling from when input type is unknown."],"exampleFix":"// before\nObservable.from(user.id); // number\n// after\nObservable.from([user.id]); // emits user.id once, then completes","handlingStrategy":"type-guard","validationCode":"if (value !== null && (typeof value === 'object' || typeof value === 'function')) { obs = Observable.from(value); } else { obs = Observable.from([value]); }","typeGuard":"function isObservableCandidate(v: unknown): v is object {\n  return v !== null && (typeof v === 'object' || typeof v === 'function');\n}","tryCatchPattern":"try { obs = Observable.from(input); } catch (e) { if (e instanceof TypeError && /is not observable/.test(e.message)) { obs = Observable.from([input]); } else throw e; }","preventionTips":["Never pass primitives to from(); wrap single values in an array.","Verify the variable is defined (imports, destructuring) before from().","Type Observable.from arguments as Observable | Iterable | AsyncIterable | Promise."],"tags":["observable-from","typeerror","type-validation","primitive"],"backgroundTag":"value-not-observable","analyzedSha":"54796b38a57e6309f9861e174737479bb3f63f61","analyzedAt":"2026-08-28T10:21:27.410Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}