{"record":{"id":"2dfeb00c4953b979","repo":"toon-format/toon","slug":"raw-string-must-not-contain-a-line-starting-with","errorCode":null,"errorMessage":"Raw string must not contain a line starting with \"${COMMENT_MARKER}\": ${JSON.stringify(value)}","messagePattern":"Raw string must not contain a line starting with \"(.+?)\": (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/toon/src/encode/raw-string.ts","lineNumber":20,"sourceCode":"import { BYTE_ORDER_MARK, COMMENT_MARKER } from '../constants.ts'\n\n// Decoders silently strip a line whose first non-space character is the comment marker,\n// and they remove a leading byte-order mark before making that test.\nconst COMMENT_LINE_PATTERN = new RegExp(`(?:^${BYTE_ORDER_MARK}?|\\\\n) *${COMMENT_MARKER}`)\n\n/**\n * Pre-formatted string that the encoder emits verbatim at a primitive value\n * position, bypassing quoting, escaping, and number/keyword detection.\n *\n * Returned from a replacer for an object or array value, it is ignored and\n * the container is encoded normally.\n */\nexport class RawString {\n  readonly value: string\n\n  constructor(value: string) {\n    if (COMMENT_LINE_PATTERN.test(value)) {\n      throw new TypeError(`Raw string must not contain a line starting with \"${COMMENT_MARKER}\": ${JSON.stringify(value)}`)\n    }\n    this.value = value\n  }\n}\n\n/** Values the encoder can emit at a primitive position. */\nexport type EncodablePrimitive = JsonPrimitive | RawString\n\n/**\n * Wraps a pre-formatted string for verbatim emission, typically returned from\n * an encode `replacer`. Compose with `escapeString` to control quoting yourself.\n *\n * @param value The exact text to emit at the value position\n * @returns A `RawString` marker honored at primitive value positions\n *\n * @example\n * ```ts\n * encode({ name: 'Ada', age: 30 }, {","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/toon-format/toon/blob/604eac266e35166bed6f5b9e3bd586e9c60a9330/packages/toon/src/encode/raw-string.ts#L2-L38","documentation":"The TOON encoder wraps user strings marked as raw in RawString, whose contract is that their content is emitted verbatim (unquoted, unescaped). Since a line starting with the comment marker would otherwise be re-parsed as a comment on decode, the constructor rejects any raw string containing such a line. This guarantees round-trip safety of raw strings.","triggerScenarios":"Calling `new RawString(value)` where any line of `value` begins with the comment marker (e.g. '#'). The check is COMMENT_LINE_PATTERN.test(value), so even embedded multi-line strings containing a comment-like line fail.","commonSituations":"Developers embedding configuration text, log excerpts, or template content that contains comment lines into raw strings for lossless encoding; copy-pasting text files with comments into raw strings.","solutions":["Strip or re-indent any lines starting with the comment marker before constructing the RawString","Pass the value as a normal (non-raw) string so the encoder quotes/escapes it instead","Catch the TypeError and surface a clear message to the user about the offending line"],"exampleFix":"// before\nconst raw = new RawString(\"# heading\\nvalue: 1\")\n// after\nconst raw = new RawString(\"\\\\# heading\\nvalue: 1\") // or a normal string: toon.encode(\"# heading\\nvalue: 1\")","handlingStrategy":"validation","validationCode":"function canBeRawString(s: string): boolean {\n  return !s.split('\\n').some(line => line.startsWith('#')) // replace '#' with your COMMENT_MARKER\n}","typeGuard":"function isSafeRawString(s: string): s is string {\n  return !COMMENT_LINE_PATTERN.test(s)\n}","tryCatchPattern":"try {\n  const raw = new RawString(userText)\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('line starting with')) {\n    // fall back to quoting/escaping the value normally\n  }\n  throw e\n}","preventionTips":["Sanitize comment-like lines before creating raw strings","Prefer normal strings unless you specifically need verbatim emission","Unit-test any user-supplied content routed through RawString"],"tags":["encoder","raw-string","input-validation","comment-marker"],"backgroundTag":"invalid-raw-string-content","analyzedSha":"604eac266e35166bed6f5b9e3bd586e9c60a9330","analyzedAt":"2026-08-31T11:09:25.043Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}