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
- Trim the metadata: keep only fields you actually need on the work item (IDs, labels, short status).
- Move large content out-of-band: store a URL or external reference instead of inline payload.
- 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
- Keep work-item metadata to small identifiers/links; store large payloads externally.
- Add a unit test asserting serialized metadata stays under 16KB for your rules.
- Pre-sanitize with normalizeFactoryRuleJsonValue to catch cycles/depth issues before size checks.
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
- Factory rule version is required.
- ${label} contains an unsupported field.
- ${label} must be an object.
- ${label}.${stage} must be an object.
- ${label}.${stage}.${source} must be an object.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/e1d383f48793714d.
Report an issue: GitHub.