{"record":{"id":"c9f3c469a993efa8","repo":"mobxjs/mobx","slug":"mobx-observable-observable-name-being-read","errorCode":null,"errorMessage":"[mobx] Observable '${observable.name_}' being read outside a reactive context.","messagePattern":"\\[mobx\\] Observable '(.+?)' being read outside a reactive context\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/mobx/src/core/derivation.ts","lineNumber":155,"sourceCode":"    const hasObservers = !!atom.observers_ && atom.observers_.size > 0\n    // Should not be possible to change observed state outside strict mode, except during initialization, see #563\n    if (\n        !globalState.allowStateChanges &&\n        (hasObservers || globalState.enforceActions === \"always\")\n    ) {\n        console.warn(\n            \"[MobX] \" +\n                (globalState.enforceActions\n                    ? \"Since strict-mode is enabled, changing (observed) observable values without using an action is not allowed. Tried to modify: \"\n                    : \"Side effects like changing state are not allowed at this point. Are you trying to modify state from, for example, a computed value or the render function of a React component? You can wrap side effects in 'runInAction' (or decorate functions with 'action') if needed. Tried to modify: \") +\n                atom.name_\n        )\n    }\n}\n\nexport function checkIfStateReadsAreAllowed(observable: IObservable) {\n    if (__DEV__ && !globalState.allowStateReads && globalState.observableRequiresReaction) {\n        console.warn(\n            `[mobx] Observable '${observable.name_}' being read outside a reactive context.`\n        )\n    }\n}\n\n/**\n * Executes the provided function `f` and tracks which observables are being accessed.\n * The tracking information is stored on the `derivation` object and the derivation is registered\n * as observer of any of the accessed observables.\n */\nexport function trackDerivedFunction<T>(derivation: IDerivation, f: () => T, context: any) {\n    const prevAllowStateReads = __DEV__ ? allowStateReadsStart(true) : true\n    changeDependenciesStateTo0(derivation)\n    // Preallocate array; will be trimmed by bindDependencies.\n    derivation.newObserving_ = new Array(\n        // Reserve constant space for initial dependencies, dynamic space otherwise.\n        // See https://github.com/mobxjs/mobx/pull/3833\n        derivation.runId_ === 0 ? 100 : derivation.observing_.length","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/mobxjs/mobx/blob/01211a698b64ea94de8e5f276ff8235fcf8ddf96/packages/mobx/src/core/derivation.ts#L137-L173","documentation":"checkIfStateReadsAreAllowed warns when an observable marked as requiring reaction (observableRequiresReaction enabled, or per-observable requiresObservable_) is read outside any reactive context (no active derivation). MobX enforces this so reads that should drive reactions aren't silently untracked, which would break the reaction contract.","triggerScenarios":"Reading an observable's .get() or property value in plain imperative code (not inside computed/reaction/observer render) while configure({ observableRequiresReaction: true }) is set, or the observable was created with requiresObservable: true (e.g. via options on observable/annotation).","commonSituations":"Debugging in the console with observableRequiresReaction left on; reading store values inside plain utility functions called outside renderers; unit tests reading observables directly; onBecomeObserved-style code paths invoked outside tracking.","solutions":["Read the value inside a reactive context: computed, reaction(), autorun(), or an observer component.","If the read is legitimately one-off (e.g. logging), disable the flag locally or globally: configure({ observableRequiresReaction: false }).","Remove requiresObservable: true from observables that are read imperatively by design.","Use toJS() in non-reactive utility code if you just need a snapshot."],"exampleFix":"// before (observableRequiresReaction: true)\nfunction logCount(store) {\n  console.log(store.count) // read outside reactive context\n}\n\n// after\nimport { autorun } from 'mobx'\nautorun(() => console.log(store.count))","handlingStrategy":"validation","validationCode":"import { _getGlobalState, configure } from 'mobx'\n// ensure reads happen in reactive contexts when this flag is on:\n// configure({ observableRequiresReaction: false }) // for imperative utility code\nfunction canReadReactively() {\n  return _getGlobalState().trackingDerivation !== null || !_getGlobalState().observableRequiresReaction\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only enable observableRequiresReaction on codebases that are fully reactive-context based.","Use toJS() for one-off snapshots in plain functions.","Wrap console/debug reads in autorun during development."],"tags":["mobx","reactive-context","untracked-read","config"],"backgroundTag":"observable-read-outside-reactive-context","analyzedSha":"01211a698b64ea94de8e5f276ff8235fcf8ddf96","analyzedAt":"2026-08-28T22:10:08.831Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}