mobxjs/mobx · info

[mobx.spy] Is a no-op in production builds

Error message

[mobx.spy] Is a no-op in production builds

What it means

spy() registers a global listener for MobX transition events, but spy instrumentation is compiled out of production builds. In a non-__DEV__ bundle the function is a no-op that only console.warns and returns an empty disposer. It exists to tell developers why their spy listener never receives events in production.

Source

Thrown at packages/mobx/src/core/spy.ts:63

    spyReport(change)
}

const END_EVENT: SpyEvent = { type: "report-end", spyReportEnd: true }

export function spyReportEnd(change?: { time?: number }) {
    if (!__DEV__) {
        return
    }
    if (change) {
        spyReport(assign({}, change, { type: "report-end" as const, spyReportEnd: true as const }))
    } else {
        spyReport(END_EVENT)
    }
}

export function spy(listener: (change: SpyEvent) => void): Lambda {
    if (!__DEV__) {
        console.warn(`[mobx.spy] Is a no-op in production builds`)
        return function () {}
    } else {
        globalState.spyListeners.push(listener)
        return once(() => {
            globalState.spyListeners = globalState.spyListeners.filter(l => l !== listener)
        })
    }
}

View on GitHub (pinned to 01211a698b)

Solutions

  1. Call spy() only in development builds, guarded by process.env.NODE_ENV !== 'production'.
  2. If you need spy events in production, build against a development MobX bundle (not recommended for perf/size).
  3. Replace production logging with trace()/onBecomeObserved on specific observables, which are not spy-gated.
  4. Ignore the warning if the spy was best-effort debugging; the returned no-op disposer is safe to call.

Example fix

// before
import { spy } from 'mobx'
spy(event => console.log(event))

// after
import { spy } from 'mobx'
if (process.env.NODE_ENV !== 'production') {
  spy(event => console.log(event))
}
Defensive patterns

Strategy: fallback

Validate before calling

function spySupported() {
  return process.env.NODE_ENV !== 'production'
}

Prevention

When it happens

Trigger: Calling spy(listener) (or mobx.spy) in an app bundled with NODE_ENV=production / a minified production MobX build, so __DEV__ is false and the early-return branch runs.

Common situations: Debugging tooling (e.g. mobx-devtools) silently inert in production; logging wrappers that call spy unconditionally; testing spy-based instrumentation against production builds of the library.

Related errors


AI-assisted analysis of mobxjs/mobx@01211a698b (2026-08-28). Data as JSON: /api/errors/c59170d386a12cb8. Report an issue: GitHub.