mastra-ai/mastra · error · FactoryRuleValidationError

Factory message prepareBinding must be a boolean.

Error message

Factory message prepareBinding must be a boolean.

What it means

The optional prepareBinding flag on a message decision must be a strict boolean when present. It gates whether the message is prepared/bound for a session, so non-boolean values would make the dispatcher's truthiness branching ambiguous and are rejected.

Source

Thrown at mastracode/factory/src/rules/validation.ts:326

        ...(value.cancelInFlight === true ? { cancelInFlight: true } : {}),
      };
    }
    case 'sendMessage': {
      assertExactKeys(
        value,
        ['type', 'idempotencyKey', 'role', 'message', 'priority', 'idleBehavior', 'prepareBinding'],
        'Factory send message decision',
      );
      const priority =
        value.priority === undefined
          ? undefined
          : enumValue(value.priority, ['medium', 'high', 'urgent'] as const, 'Factory message priority');
      const idleBehavior =
        value.idleBehavior === undefined
          ? undefined
          : enumValue(value.idleBehavior, ['persist', 'wake'] as const, 'Factory message idle behavior');
      if (value.prepareBinding !== undefined && typeof value.prepareBinding !== 'boolean') {
        throw new FactoryRuleValidationError('Factory message prepareBinding must be a boolean.');
      }
      return {
        type,
        ...commonCommitFields(value),
        role: boundedString(value.role, 'Factory message role', MAX_ROLE_LENGTH, IDENTIFIER_RE),
        message: boundedString(value.message, 'Factory message', MAX_MESSAGE_LENGTH),
        ...(priority ? { priority } : {}),
        ...(idleBehavior ? { idleBehavior } : {}),
        ...(value.prepareBinding === true ? { prepareBinding: true } : {}),
      };
    }
    case 'notify': {
      assertExactKeys(value, ['type', 'idempotencyKey', 'title', 'body', 'level'], 'Factory notify decision');
      const body = optionalBoundedString(value.body, 'Factory notification body', MAX_MESSAGE_LENGTH);
      const level =
        value.level === undefined
          ? undefined
          : enumValue(value.level, ['info', 'warning', 'error'] as const, 'Factory notification level');

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Coerce the incoming value to a strict boolean (=== true or === 'true') before emitting, or omit the field entirely with undefined.
  2. Replace null with undefined — null is a defined, non-boolean value and will throw.
  3. Validate/parse rule config with a schema (zod/yup) that enforces boolean at load time.

Example fix

// before
prepareBinding: options.prepareBinding // 'true' from YAML
// after
prepareBinding: options.prepareBinding === undefined ? undefined : options.prepareBinding === true
Defensive patterns

Strategy: type-guard

Validate before calling

function checkPrepareBinding(d) {
  if (d.prepareBinding !== undefined && typeof d.prepareBinding !== 'boolean') {
    throw new Error('prepareBinding must be boolean or omitted');
  }
}

Type guard

function hasValidPrepareBinding(d: { prepareBinding?: unknown }): d is { prepareBinding?: boolean } {
  return d.prepareBinding === undefined || typeof d.prepareBinding === 'boolean';
}

Try / catch

try {
  commitDecision(decision);
} catch (e) {
  if (e instanceof FactoryRuleValidationError && /prepareBinding must be a boolean/.test(e.message)) {
    const { prepareBinding, ...rest } = decision;
    return commitDecision({ ...rest, prepareBinding: prepareBinding === true });
  }
  throw e;
}

Prevention

When it happens

Trigger: Emitting a FactoryCommitDecision of the message type with value.prepareBinding defined but not typeof 'boolean' — e.g. prepareBinding: 'yes', 1, or null from parsed config or interpolated templates.

Common situations: YAML/JSON rule configuration where the flag arrives as a string; JavaScript rule authors using 1/0; environment-variable-driven rules where all values are strings.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/1373ca3caf72c8b8. Report an issue: GitHub.