{"record":{"id":"3703e018c023508d","repo":"mastra-ai/mastra","slug":"invalid-signal-xml-label-name","errorCode":null,"errorMessage":"Invalid signal XML ${label}: ${name}","messagePattern":"Invalid signal XML (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/agent/signals.ts","lineNumber":237,"sourceCode":"        : signal.acceptedAt\n          ? new Date(signal.acceptedAt)\n          : undefined,\n  };\n}\n\nfunction escapeXml(value: string): string {\n  return value.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');\n}\n\nfunction escapeXmlAttribute(value: string): string {\n  return escapeXml(value).replaceAll('\"', '&quot;');\n}\n\nconst XML_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_.-]*$/;\n\nfunction assertXmlName(name: string, label: string): void {\n  if (!XML_NAME_PATTERN.test(name)) {\n    throw new Error(`Invalid signal XML ${label}: ${name}`);\n  }\n}\n\nfunction signalAttributesToXml(attributes?: AgentSignalAttributes): string {\n  if (!attributes) {\n    return '';\n  }\n\n  const serialized = Object.entries(attributes)\n    .filter((entry): entry is [string, string | number | boolean] => entry[1] !== null && entry[1] !== undefined)\n    .map(([key, value]) => {\n      assertXmlName(key, 'attribute name');\n      return `${key}=\"${escapeXmlAttribute(String(value))}\"`;\n    })\n    .join(' ');\n\n  return serialized ? ` ${serialized}` : '';\n}","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/agent/signals.ts#L219-L255","documentation":"Signal tag names (and attribute names) are serialized into XML, so they must match XML's Name production: start with a letter or underscore, followed by letters, digits, underscore, dot, or hyphen. assertXmlName enforces this before emitting markup, because an invalid name would produce malformed/unparseable XML in the model stream.","triggerScenarios":"Creating a signal whose `tagName` (or attribute name, labeled by `label`) contains spaces, digits at the start, special characters like '<', ':', '/', or is empty — e.g. tagName 'my reminder' or '1-reminder'.","commonSituations":"Deriving tagName dynamically from user input or file/event names that contain spaces or slashes; using a camelCase tagName with invalid leading characters; forgetting to sanitize IDs used as tag names.","solutions":["Rename the tagName to satisfy the pattern /^[A-Za-z_][A-Za-z0-9_.-]*$/, e.g. 'system-reminder', 'user_note'.","Sanitize dynamic names before creating the signal: strip invalid characters and prefix with a letter/underscore if it starts with a digit.","If the display label needs spaces/other chars, put it in an attribute or content, not the tag name.","Pre-validate with the same regex before calling createSignal when names come from user input."],"exampleFix":"// before\ncreateSignal({ type: 'reactive', tagName: 'my reminder!', contents });\n// after\ncreateSignal({ type: 'reactive', tagName: 'my-reminder', contents });","handlingStrategy":"validation","validationCode":"const XML_NAME = /^[A-Za-z_][A-Za-z0-9_.-]*$/;\nif (!XML_NAME.test(tagName)) throw new TypeError(`tagName ${tagName} is not a valid XML name`);","typeGuard":"function isValidXmlName(name: string): boolean {\n  return /^[A-Za-z_][A-Za-z0-9_.-]*$/.test(name);\n}","tryCatchPattern":"try {\n  const signal = createSignal({ type: 'reactive', tagName, contents });\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Invalid signal XML')) {\n    signal = createSignal({ type: 'reactive', tagName: sanitizeXmlName(tagName), contents });\n  } else throw e;\n}","preventionTips":["Sanitize dynamic tag names: replace invalid chars and prefix digits with '_'","Keep tag names to [A-Za-z0-9_.-] and never start with a digit","Put human-readable labels in attributes, not tag names"],"tags":["signals","xml","validation"],"backgroundTag":"invalid-xml-tag-name","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}