mobxjs/mobx · warning

[mobx] (error in reaction '${this.name_}' suppressed, fix er

Error message

[mobx] (error in reaction '${this.name_}' suppressed, fix error of causing action below)

What it means

When a reaction or observer component throws, MobX catches the error (unless error boundaries are disabled) and logs it. If the error was thrown while MobX was already running an action on behalf of that reaction (suppressReactionErrors is set), the original error is logged first and MobX additionally prints this warning telling you the reaction's own error report was suppressed and to fix the underlying action error listed above it.

Source

Thrown at packages/mobx/src/core/reaction.ts:207

    }

    reportExceptionInDerivation_(error: any) {
        if (this.errorHandler_) {
            this.errorHandler_(error, this)
            return
        }

        if (globalState.disableErrorBoundaries) {
            throw error
        }

        const message = __DEV__
            ? `[mobx] Encountered an uncaught exception that was thrown by a reaction or observer component, in: '${this}'`
            : `[mobx] uncaught error in '${this}'`
        if (!globalState.suppressReactionErrors) {
            console.error(message, error)
            /** If debugging brought you here, please, read the above message :-). Tnx! */
        } else if (__DEV__) { console.warn(`[mobx] (error in reaction '${this.name_}' suppressed, fix error of causing action below)`) } // prettier-ignore

        if (__DEV__ && isSpyEnabled()) {
            spyReport({
                type: "error",
                name: this.name_,
                message,
                error: "" + error
            })
        }

        globalState.globalReactionErrorHandlers.forEach(f => f(error, this))
    }

    dispose() {
        if (!this.isDisposed) {
            this.isDisposed = true
            if (!this.isRunning) {
                // if disposed while running, clean up later. Maybe not optimal, but rare case

View on GitHub (pinned to 01211a698b)

Solutions

  1. Fix the error printed ABOVE this warning — the suppressed message is secondary; the causing action's error is the root cause
  2. Wrap risky action bodies in try/catch or validate state before mutating
  3. Temporarily set configure({ disableErrorBoundaries: true }) in dev to get the full uncaught stack
  4. Ensure async work inside reactions handles rejections explicitly

Example fix

// before
reaction(() => data.value, v => process(v)) // process throws
// after
reaction(() => data.value, v => {
    try { process(v) } catch (e) { console.error('action failed', e) }
})
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

function isSuppressedReactionWarning(msg: string): boolean {
    return msg.includes("error in reaction") && msg.includes('suppressed')
}

Try / catch

try {
    runInAction(() => mutateState())
} catch (e) {
    // root-cause: this is the error whose report was suppressed in the reaction
    console.error('Causing action failed — fix this, not the suppressed warning', e)
    throw e
}

Prevention

When it happens

Trigger: An exception thrown inside an action that runs as part of a reaction's effect (e.g. inside runInAction called from a reaction callback, or an observer's render triggering an action) in a __DEV__ build with the default error boundaries enabled.

Common situations: Actions mutating state that fails validation and throws while a reaction is processing; unhandled promise rejections inside reaction callbacks; debugging cascading errors where the first stack line is the real one.

Related errors


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