facebook/react · error · Error

Only objects or functions can be passed to taintObjectRefere

Error message

Only objects or functions can be passed to taintObjectReference. Try taintUniqueValue instead.

What it means

taintObjectReference registers identity-based taints via a WeakMap and only accepts objects or functions. Strings and bigints are value types with no stable identity, so passing one throws early with a hint to use taintUniqueValue, which is the registry built for unique scalar values.

Source

Thrown at packages/react/src/ReactTaint.js:127

  } else {
    existingEntry.count++;
  }
  if (finalizationRegistry !== null) {
    finalizationRegistry.register(lifetime, entryValue);
  }
}

export function taintObjectReference(
  message: ?string,
  object: Reference,
): void {
  if (!enableTaint) {
    throw new Error('Not implemented.');
  }
  // eslint-disable-next-line react-internal/safe-string-coercion
  message = '' + (message || defaultMessage);
  if (typeof object === 'string' || typeof object === 'bigint') {
    throw new Error(
      'Only objects or functions can be passed to taintObjectReference. Try taintUniqueValue instead.',
    );
  }
  if (
    // $FlowFixMe[invalid-compare]
    object === null ||
    (typeof object !== 'object' && typeof object !== 'function')
  ) {
    throw new Error(
      'Only objects or functions can be passed to taintObjectReference.',
    );
  }
  TaintRegistryObjects.set(object, message);
}

View on GitHub (pinned to eafeac097b)

Solutions

  1. Use taintUniqueValue(message, lifetimeObject, secretString) for strings and bigints
  2. Keep taintObjectReference for object/function references only
  3. Double-check parameter order: message, then the tainted thing (plus lifetime for taintUniqueValue)

Example fix

// before
taintObjectReference(msg, apiKey); // apiKey is a string -> throws

// after
taintUniqueValue(msg, requestContext, apiKey);
Defensive patterns

Strategy: type-guard

Validate before calling

// Route strings/bigints to taintUniqueValue
function taintValue(message: string, lifetime: object, value: unknown) {
  if (typeof value === 'string' || typeof value === 'bigint') {
    taintUniqueValue(message, lifetime, value);
  } else {
    taintObjectReference(message, value);
  }
}

Type guard

const isScalarSecret = (v: unknown): v is string | bigint =>
  typeof v === 'string' || typeof v === 'bigint';

Prevention

When it happens

Trigger: Calling taintObjectReference(message, 'some-secret-string') or taintObjectReference(message, 123n) — passing a string/bigint where the object argument goes.

Common situations: Argument-order confusion between the two taint APIs (message first, then value); upgrading security review fixes that swapped the intended API for secrets stored as strings.

Related errors


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/c16da74438704fe2. Report an issue: GitHub.