mastra-ai/mastra · error · FactoryRuleValidationError

Factory rules.linear must be an object.

Error message

Factory rules.linear must be an object.

What it means

Thrown by assertFactoryRules when rules.linear is present but is not a plain object. Like rules.github, the linear section must be an object keyed by Linear event names. This is eager configuration validation so malformed rule shapes fail immediately.

Source

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

    if (!isPlainObject(leaf))
      throw new FactoryRuleValidationError(`Factory rules.tools.${toolName} must be an object.`);
    assertExactKeys(leaf, ['onResult'], `Factory rules.tools.${toolName}`);
    if (leaf.onResult !== undefined && typeof leaf.onResult !== 'function') {
      throw new FactoryRuleValidationError(`Factory rules.tools.${toolName}.onResult must be a function.`);
    }
  }

  if (!isPlainObject(rules.github)) throw new FactoryRuleValidationError('Factory rules.github must be an object.');
  for (const [event, leaf] of Object.entries(rules.github)) {
    enumValue(event, FACTORY_GITHUB_EVENTS, 'Factory GitHub event');
    if (!isPlainObject(leaf)) throw new FactoryRuleValidationError(`Factory rules.github.${event} must be an object.`);
    assertExactKeys(leaf, ['onEvent'], `Factory rules.github.${event}`);
    if (leaf.onEvent !== undefined && typeof leaf.onEvent !== 'function') {
      throw new FactoryRuleValidationError(`Factory rules.github.${event}.onEvent must be a function.`);
    }
  }

  if (!isPlainObject(rules.linear)) throw new FactoryRuleValidationError('Factory rules.linear must be an object.');
  for (const [event, leaf] of Object.entries(rules.linear)) {
    enumValue(event, FACTORY_LINEAR_EVENTS, 'Factory Linear event');
    if (!isPlainObject(leaf)) throw new FactoryRuleValidationError(`Factory rules.linear.${event} must be an object.`);
    assertExactKeys(leaf, ['onEvent'], `Factory rules.linear.${event}`);
    if (leaf.onEvent !== undefined && typeof leaf.onEvent !== 'function') {
      throw new FactoryRuleValidationError(`Factory rules.linear.${event}.onEvent must be a function.`);
    }
  }
}

function commonCommitFields(value: Record<string, unknown>): { idempotencyKey: string } {
  return {
    idempotencyKey: boundedString(value.idempotencyKey, 'Factory decision idempotencyKey', MAX_IDEMPOTENCY_KEY_LENGTH),
  };
}

export function validateFactoryRuleDecision(value: unknown, causalDepth = 0): FactoryRuleDecision {
  if (causalDepth > MAX_FACTORY_RULE_CAUSAL_DEPTH) {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Set rules.linear to a plain object keyed by event name, e.g. { issue_assigned: { onEvent: fn } }
  2. Check typeof and Array.isArray on your config before calling prepare
  3. If the section may be absent, omit the key rather than passing null
  4. Convert Map/array structures into a plain record before validation

Example fix

// before
prepare({ rules: { linear: [ { event: 'issue_assigned', onEvent: fn } ] } })
// after
prepare({ rules: { linear: { issue_assigned: { onEvent: fn } } } })
Defensive patterns

Strategy: validation

Validate before calling

if (rules?.linear !== undefined &&
    (typeof rules.linear !== 'object' || rules.linear === null || Array.isArray(rules.linear))) {
  throw new TypeError('rules.linear must be a plain object keyed by event name');
}

Type guard

const isLinearRules = (v) =>
  v === undefined || (typeof v === 'object' && v !== null && !Array.isArray(v));

Try / catch

try {
  prepare({ rules });
} catch (e) {
  if (e instanceof FactoryRuleValidationError && e.message === 'Factory rules.linear must be an object.') {
    console.error('linear rules section malformed:', typeof rules.linear);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling prepare(...) or defaultFactoryRules(...) with rules: { linear: [] } (array), { linear: null }, { linear: 'default' }, { linear: someFn }, or a class instance.

Common situations: Passing an array of rule objects instead of a keyed map; null from a failed config load; a Map instance (not plain object); copying a github array-style config to linear.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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