{"record":{"id":"bca86fe444dd2be8","repo":"mastra-ai/mastra","slug":"factory-rules-linear-must-be-an-object","errorCode":null,"errorMessage":"Factory rules.linear must be an object.","messagePattern":"Factory rules\\.linear must be an object\\.","errorType":"validation","errorClass":"FactoryRuleValidationError","httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/rules/validation.ts","lineNumber":188,"sourceCode":"    if (!isPlainObject(leaf))\n      throw new FactoryRuleValidationError(`Factory rules.tools.${toolName} must be an object.`);\n    assertExactKeys(leaf, ['onResult'], `Factory rules.tools.${toolName}`);\n    if (leaf.onResult !== undefined && typeof leaf.onResult !== 'function') {\n      throw new FactoryRuleValidationError(`Factory rules.tools.${toolName}.onResult must be a function.`);\n    }\n  }\n\n  if (!isPlainObject(rules.github)) throw new FactoryRuleValidationError('Factory rules.github must be an object.');\n  for (const [event, leaf] of Object.entries(rules.github)) {\n    enumValue(event, FACTORY_GITHUB_EVENTS, 'Factory GitHub event');\n    if (!isPlainObject(leaf)) throw new FactoryRuleValidationError(`Factory rules.github.${event} must be an object.`);\n    assertExactKeys(leaf, ['onEvent'], `Factory rules.github.${event}`);\n    if (leaf.onEvent !== undefined && typeof leaf.onEvent !== 'function') {\n      throw new FactoryRuleValidationError(`Factory rules.github.${event}.onEvent must be a function.`);\n    }\n  }\n\n  if (!isPlainObject(rules.linear)) throw new FactoryRuleValidationError('Factory rules.linear must be an object.');\n  for (const [event, leaf] of Object.entries(rules.linear)) {\n    enumValue(event, FACTORY_LINEAR_EVENTS, 'Factory Linear event');\n    if (!isPlainObject(leaf)) throw new FactoryRuleValidationError(`Factory rules.linear.${event} must be an object.`);\n    assertExactKeys(leaf, ['onEvent'], `Factory rules.linear.${event}`);\n    if (leaf.onEvent !== undefined && typeof leaf.onEvent !== 'function') {\n      throw new FactoryRuleValidationError(`Factory rules.linear.${event}.onEvent must be a function.`);\n    }\n  }\n}\n\nfunction commonCommitFields(value: Record<string, unknown>): { idempotencyKey: string } {\n  return {\n    idempotencyKey: boundedString(value.idempotencyKey, 'Factory decision idempotencyKey', MAX_IDEMPOTENCY_KEY_LENGTH),\n  };\n}\n\nexport function validateFactoryRuleDecision(value: unknown, causalDepth = 0): FactoryRuleDecision {\n  if (causalDepth > MAX_FACTORY_RULE_CAUSAL_DEPTH) {","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/rules/validation.ts#L170-L206","documentation":"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.","triggerScenarios":"Calling prepare(...) or defaultFactoryRules(...) with rules: { linear: [] } (array), { linear: null }, { linear: 'default' }, { linear: someFn }, or a class instance.","commonSituations":"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.","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"],"exampleFix":"// before\nprepare({ rules: { linear: [ { event: 'issue_assigned', onEvent: fn } ] } })\n// after\nprepare({ rules: { linear: { issue_assigned: { onEvent: fn } } } })","handlingStrategy":"validation","validationCode":"if (rules?.linear !== undefined &&\n    (typeof rules.linear !== 'object' || rules.linear === null || Array.isArray(rules.linear))) {\n  throw new TypeError('rules.linear must be a plain object keyed by event name');\n}","typeGuard":"const isLinearRules = (v) =>\n  v === undefined || (typeof v === 'object' && v !== null && !Array.isArray(v));","tryCatchPattern":"try {\n  prepare({ rules });\n} catch (e) {\n  if (e instanceof FactoryRuleValidationError && e.message === 'Factory rules.linear must be an object.') {\n    console.error('linear rules section malformed:', typeof rules.linear);\n  } else throw e;\n}","preventionTips":["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"],"tags":["validation","factory-rules","configuration"],"backgroundTag":"schema-validation-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}