mastra-ai/mastra · error · FactoryRuleValidationError

Rule metadata is too large.

Error message

Rule metadata is too large.

What it means

sanitizeMetadata validates the optional metadata payload of an upsertLinkedWorkItem rule decision. After normalizing the value to JSON-safe form, it serializes it and rejects it if the JSON exceeds MAX_METADATA_JSON_LENGTH (16,384 characters). The library caps metadata size to keep persisted decisions bounded and storage-friendly.

Source

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

    const sanitized: Record<string, FactoryRuleJsonValue> = {};
    for (const [key, entry] of entries) {
      const normalizedKey = boundedString(key, 'Rule metadata key', 128, IDENTIFIER_RE);
      sanitized[normalizedKey] = SENSITIVE_KEY_RE.test(normalizedKey)
        ? '[REDACTED]'
        : normalizeFactoryRuleJsonValue(entry, depth + 1, seen);
    }
    return sanitized;
  } finally {
    seen.delete(value as object);
  }
}

function sanitizeMetadata(value: unknown): Record<string, FactoryRuleJsonValue> | undefined {
  if (value === undefined) return undefined;
  const sanitized = normalizeFactoryRuleJsonValue(value);
  if (!isPlainObject(sanitized)) throw new FactoryRuleValidationError('Rule metadata must be an object.');
  if (JSON.stringify(sanitized).length > MAX_METADATA_JSON_LENGTH) {
    throw new FactoryRuleValidationError('Rule metadata is too large.');
  }
  return sanitized;
}

function validateBoardRules(rules: unknown, label: string): asserts rules is FactoryBoardRules {
  if (!isPlainObject(rules)) throw new FactoryRuleValidationError(`${label} must be an object.`);
  for (const [stage, sources] of Object.entries(rules)) {
    enumValue(stage, FACTORY_RULE_STAGES, `${label} stage`);
    if (!isPlainObject(sources)) throw new FactoryRuleValidationError(`${label}.${stage} must be an object.`);
    for (const [source, leaf] of Object.entries(sources)) {
      enumValue(source, FACTORY_RULE_SOURCES, `${label}.${stage} source`);
      if (!isPlainObject(leaf)) throw new FactoryRuleValidationError(`${label}.${stage}.${source} must be an object.`);
      assertExactKeys(leaf, ['onEnter', 'onExit'], `${label}.${stage}.${source}`);
      for (const handler of Object.values(leaf)) {
        if (handler !== undefined && typeof handler !== 'function') {
          throw new FactoryRuleValidationError(`${label}.${stage}.${source} handlers must be functions.`);
        }
      }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Trim the metadata: keep only fields you actually need on the work item (IDs, labels, short status).
  2. Move large content out-of-band: store a URL or external reference instead of inline payload.
  3. Pre-check size with JSON.stringify(metadata).length <= 16384 before constructing the decision.

Example fix

// before
metadata: { fullBody: issue.body, comments: issue.comments, logs: runLogs }
// after
metadata: { issueId: issue.id, url: issue.url, labelCount: issue.labels.length }
Defensive patterns

Strategy: validation

Validate before calling

function checkMetadataSize(metadata) {
  if (metadata === undefined) return;
  const json = JSON.stringify(metadata);
  if (json.length > 16384) throw new Error(`Rule metadata JSON is ${json.length} chars; max is 16384`);
}
checkMetadataSize(decision.metadata);

Try / catch

try {
  commit(decision);
} catch (e) {
  if (e.name === 'FactoryRuleValidationError' && /metadata is too large/.test(e.message)) {
    decision.metadata = compactMetadata(decision.metadata); // strip bulky fields and retry once
    commit(decision);
  } else throw e;
}

Prevention

When it happens

Trigger: Passing a metadata object longer than 16,384 characters when serialized to JSON in the metadata field of a {type:'upsertLinkedWorkItem', ...} decision, which reaches sanitizeMetadata via validateFactoryRuleDecision (and its public wrapper metadata).

Common situations: Embedding large API response payloads, logs, or long descriptions into work-item metadata; accumulating many fields per item; copying whole issue bodies into metadata instead of a URL or excerpt.

Related errors


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