necolas/react-native-web · error · Error

Unrecognized signal `${signal}` or state `${curState}` for T

Error message

Unrecognized signal `${signal}` or state `${curState}` for Touchable responder `${responderID}`

What it means

Touchable implements an explicit responder state machine; _receiveSignal looks up Transitions[curState][signal] to find the next state. If the (state, signal) pair has no defined transition, internal invariants are broken and it throws. This is almost always a library bug or an unbalanced responder event sequence, not user error.

Source

Thrown at packages/react-native-web/src/exports/Touchable/index.js:767

  },

  /**
   * Receives a state machine signal, performs side effects of the transition
   * and stores the new state. Validates the transition as well.
   *
   * @param {Signals} signal State machine signal.
   * @throws Error if invalid state transition or unrecognized signal.
   * @sideeffects
   */
  _receiveSignal: function (signal: Signal, e: PressEvent) {
    const responderID = this.state.touchable.responderID;
    const curState = this.state.touchable.touchState;
    const nextState = Transitions[curState] && Transitions[curState][signal];
    if (!responderID && signal === Signals.RESPONDER_RELEASE) {
      return;
    }
    if (!nextState) {
      throw new Error(
        'Unrecognized signal `' +
          signal +
          '` or state `' +
          curState +
          '` for Touchable responder `' +
          responderID +
          '`'
      );
    }
    if (nextState === States.ERROR) {
      throw new Error(
        'Touchable cannot transition from `' +
          curState +
          '` to `' +
          signal +
          '` for responder `' +
          responderID +
          '`'

View on GitHub (pinned to a9de220ba9)

Solutions

  1. Report the (signal, state, responderID) pair to react-native-web — likely a state-machine bug; include reproduction steps.
  2. Check for custom code that calls Touchable internals (responder callbacks) out of order.
  3. Verify no overlapping touch handling (nested Touchables/gesture layers) dispatches events on the same responder twice.
  4. Update react-native-web; the fix may already exist.

Example fix

// before
touchable._receiveSignal(Signals.RESPONDER_RELEASE, id); // called without a grant
// after
// drive the responder only through real pointer events; remove manual signal dispatch
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure responder events come only from real pointer handlers:
if (!isNativePointerEvent(event)) throw new Error('Do not dispatch Touchable signals manually');

Type guard

const hasValidTransition = (state, signal) => Boolean(Transitions[state] && Transitions[state][signal]);

Try / catch

try { touchable._receiveSignal(signal, id); } catch (e) { if (/Unrecognized signal/.test(e.message)) resetTouchableState(touchable); else throw e; }

Prevention

When it happens

Trigger: Dispatching a touch signal (e.g. RESPONDER_RELEASE, RESPONDER_GRANT, RESPONDER_TERMINATE) while the Touchable is in a state with no registered transition for it — e.g. a release arriving in a state where it wasn't granted, or duplicate grant signals.

Common situations: Programmatically invoking internal responder methods; synthetic event sequences from nested/overlapping touchables or third-party gesture handling; edge cases during rapid taps where grant/release interleave unexpectedly.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of necolas/react-native-web@a9de220ba9 (2026-09-01). Data as JSON: /api/errors/545747fefcc2d3e5. Report an issue: GitHub.