mastra-ai/mastra · error · FactoryRuleValidationError
Factory rules.github must be an object.
Error message
Factory rules.github must be an object.
What it means
assertFactoryRules requires rules.github to be a plain object whose keys are valid FACTORY_GITHUB_EVENTS values mapping to { onEvent? } leaves. This error fires when rules.github itself is not a plain object.
Source
Thrown at mastracode/factory/src/rules/validation.ts:178
export function assertFactoryRules(rules: unknown): asserts rules is FactoryRules {
if (!isPlainObject(rules)) throw new FactoryRuleValidationError('Factory rules must be an object.');
assertExactKeys(rules, ['version', 'work', 'review', 'tools', 'github', 'linear'], 'Factory rules');
boundedString(rules.version, 'Factory rule version', MAX_VERSION_LENGTH);
validateBoardRules(rules.work, 'Factory rules.work');
validateBoardRules(rules.review, 'Factory rules.review');
if (!isPlainObject(rules.tools)) throw new FactoryRuleValidationError('Factory rules.tools must be an object.');
for (const [toolName, leaf] of Object.entries(rules.tools)) {
boundedString(toolName, 'Factory tool name', 128, IDENTIFIER_RE);
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.`);
}
}View on GitHub (pinned to 75dd419e61)
Solutions
- Set rules.github to an object, using {} when no GitHub rules are needed.
- Move legacy GitHub hook config into the rules.github shape with valid event keys.
- Default on load: rules.github = rules.github ?? {}.
Example fix
// before
{ version: '1', work: {}, review: {}, tools: {}, github: undefined, linear: {} }
// after
{ version: '1', work: {}, review: {}, tools: {}, github: {}, linear: {} } Defensive patterns
Strategy: validation
Validate before calling
if (rules.github !== undefined && (rules.github === null || typeof rules.github !== 'object' || Array.isArray(rules.github))) {
throw new Error('rules.github must be a plain object (use {} if empty)');
} Type guard
const isGithubRules = (v: unknown): v is Record<string, { onEvent?: (event: unknown) => unknown }> =>
typeof v === 'object' && v !== null && !Array.isArray(v); Try / catch
try {
assertFactoryRules(rules);
} catch (e) {
if (e.name === 'FactoryRuleValidationError' && /rules\.github must be an object/.test(e.message)) {
rules.github = {}; // default empty GitHub rules and revalidate
assertFactoryRules(rules);
} else throw e;
} Prevention
- Include github: {} in rules templates even when unused.
- Default optional sections with ?? {} at config load time.
- Keep a type-annotated FactoryRules object so missing sections are caught before runtime.
When it happens
Trigger: rules.github set to null, undefined, an array, a Map, or a primitive while validating the full rules object via prepare or defaultFactoryRules.
Common situations: GitHub rules omitted from config and stubbed with null; destructuring/migration code that dropped the github section; an older rules schema where GitHub hooks lived elsewhere and github was never populated.
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
- ${label}.${stage} must be an object.
- ${label}.${stage}.${source} must be an object.
- Factory rules.tools must be an object.
- GitHub installation id is invalid.
- GitHub pull requests require an owner/repository source.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/4f1786174a8253f8.
Report an issue: GitHub.