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
- Set rules.linear to a plain object keyed by event name, e.g. { issue_assigned: { onEvent: fn } }
- Check typeof and Array.isArray on your config before calling prepare
- If the section may be absent, omit the key rather than passing null
- 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
- Model linear rules as a record, never an array
- Omit the key when there are no linear rules
- Convert Map instances to plain objects first
- Validate the whole rules object with a schema before prepare
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
- Factory rules.github.${event} must be an object.
- Factory rules.linear.${event} must be an object.
- Google RBAC roleMapping is required.
- Cookie password must be at least 32 characters. Set OKTA_COO
- heartbeatMs must be a finite number no greater than ${MAX_TI
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/bca86fe444dd2be8.
Report an issue: GitHub.