{"record":{"id":"adf8a57b153c37a9","repo":"mastra-ai/mastra","slug":"label-is-invalid","errorCode":null,"errorMessage":"${label} is invalid.","messagePattern":"(.+?) is invalid\\.","errorType":"validation","errorClass":"FactoryRuleValidationError","httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/rules/validation.ts","lineNumber":75,"sourceCode":"\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n  if (typeof value !== 'object' || value === null || Array.isArray(value)) return false;\n  const prototype = Object.getPrototypeOf(value);\n  return prototype === Object.prototype || prototype === null;\n}\n\nfunction assertExactKeys(value: Record<string, unknown>, keys: readonly string[], label: string): void {\n  const allowed = new Set(keys);\n  if (Object.keys(value).some(key => !allowed.has(key))) {\n    throw new FactoryRuleValidationError(`${label} contains an unsupported field.`);\n  }\n}\n\nfunction boundedString(value: unknown, label: string, max: number, pattern?: RegExp): string {\n  if (typeof value !== 'string') throw new FactoryRuleValidationError(`${label} must be a string.`);\n  const normalized = value.trim();\n  if (normalized.length === 0 || normalized.length > max || (pattern && !pattern.test(normalized))) {\n    throw new FactoryRuleValidationError(`${label} is invalid.`);\n  }\n  return normalized;\n}\n\nfunction optionalBoundedString(value: unknown, label: string, max: number): string | undefined {\n  if (value === undefined) return undefined;\n  return boundedString(value, label, max);\n}\n\nfunction enumValue<T extends string>(value: unknown, allowed: readonly T[], label: string): T {\n  if (typeof value !== 'string' || !allowed.includes(value as T)) {\n    throw new FactoryRuleValidationError(`${label} is invalid.`);\n  }\n  return value as T;\n}\n\nexport function normalizeFactoryRuleJsonValue(\n  value: unknown,","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/rules/validation.ts#L57-L93","documentation":"After confirming the value is a string, boundedString rejects it if it is empty after trimming, exceeds the field's max length (e.g. idempotencyKey 256, message 8192, role 32, version 128), or fails the optional pattern (IDENTIFIER_RE for roles/keys, SKILL_NAME_RE for skill names). The message includes the field label so the developer knows which field failed.","triggerScenarios":"Passing an empty or whitespace-only string; a role like 'My Role!' failing IDENTIFIER_RE; a skillName like 'My Skill' failing SKILL_NAME_RE (must be kebab-case lowercase); an oversized message (>8192 chars) or title (>512) or idempotencyKey (>256); a metadata key with characters outside [a-z0-9_-] or longer than 128.","commonSituations":"Whitespace-padded values from user input or clipboard paste, skill names with spaces or uppercase from hand-written config, very long error text stuffed into the message field, auto-generated ids with colons or slashes (UUID with dashes is fine, but ':' is not).","solutions":["Trim the value yourself and check it is non-empty before passing it.","For role/key fields, use /^[a-z0-9][a-z0-9_-]*$/i-compatible identifiers (letters, digits, underscore, hyphen only).","For skillName, use lowercase kebab-case, e.g. 'run-tests'.","Truncate long text to the documented max (message 8192, title 512, reason 512, arguments 4096) before building the decision."],"exampleFix":"// before\nrole: 'Backend Dev'\n// after\nrole: 'backend-dev'","handlingStrategy":"validation","validationCode":"const check = (s: string, max: number, re?: RegExp) => {\n  const t = s.trim();\n  if (!t || t.length > max || (re && !re.test(t))) throw new RangeError(`invalid ${s.slice(0, 20)}`);\n};\ncheck(role, 32, /^[a-z0-9][a-z0-9_-]*$/i);","typeGuard":"const isValidIdentifier = (v: unknown): v is string => typeof v === 'string' && /^[a-z0-9][a-z0-9_-]*$/i.test(v.trim());","tryCatchPattern":"try {\n  validateFactoryRuleDecision(decision);\n} catch (e) {\n  if (e instanceof FactoryRuleValidationError && e.message.endsWith('is invalid.')) {\n    throw new Error(`Constraint violation, fix value/format: ${e.message}`);\n  }\n  throw e;\n}","preventionTips":["Trim and length-check user-derived strings before passing them to decisions.","Use lowercase kebab-case for skill names and identifier-safe roles.","Know the limits: idempotencyKey 256, role 32, reason/title 512, arguments 4096, message 8192, metadata key 128.","Add unit tests that assert your rule-generated strings match the documented patterns."],"tags":["validation","constraints","string-format"],"backgroundTag":"schema-validation-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}