{"record":{"id":"3e1063c0b8f8a8d2","repo":"can1357/oh-my-pi","slug":"unexpected-character-c-in-src","errorCode":null,"errorMessage":"unexpected character '${c}' in \"${src}\"","messagePattern":"unexpected character '(.+?)' in \"(.+?)\"","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/ir.ts","lineNumber":281,"sourceCode":"\t\t\t\ttoks.push({ t: \"op\", v: `${c}=` });\n\t\t\t\ti += 2;\n\t\t\t} else {\n\t\t\t\ttoks.push({ t: \"op\", v: c });\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tif (c === \"=\" && src[i + 1] === \"=\") {\n\t\t\ttoks.push({ t: \"op\", v: \"==\" });\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (SIMPLE_OPS.includes(c)) {\n\t\t\ttoks.push({ t: \"op\", v: c });\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tthrow new OmpTypeError(`unexpected character '${c}' in \"${src}\"`);\n\t}\n\treturn toks;\n}\n\n// ── string-definition parser ─────────────────────────────────────────────────\n\nconst CMP: Record<string, true> = { \"<\": true, \"<=\": true, \">\": true, \">=\": true };\n\nconst KEYWORDS: Record<string, () => IR> = {\n\tnumber: () => ({ k: \"number\" }),\n\t\"number.integer\": () => ({ k: \"number\", int: true }),\n\tboolean: () => ({ k: \"boolean\" }),\n\tbigint: () => ({ k: \"bigint\" }),\n\tsymbol: () => ({ k: \"symbol\" }),\n\tnever: () => ({ k: \"never\" }),\n\tnull: () => ({ k: \"null\" }),\n\tundefined: () => ({ k: \"undefined\" }),\n\tunknown: () => ({ k: \"unknown\" }),","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/ir.ts#L263-L299","documentation":"The tokenizer hit a character that cannot start any token in an omptype string definition. Only digits, letters/_/$, quotes, '/', and known operators (SIMPLE_OPS, <, <=, >, >=, ==) are recognized; anything else (e.g. '@', '!', ';', ':', unicode punctuation) is rejected so that typos fail loudly instead of producing a mis-parsed schema.","triggerScenarios":"Any parse of a string definition containing an unsupported character: 'string@', 'number!', 'string; number', stray quotes/braces outside their grammar, or smart quotes ('“string”') pasted from docs.","commonSituations":"Copy-pasting type expressions from blogs/docs that contain smart quotes or non-ASCII dashes; typos like 'number!!'; using characters from a different type syntax (e.g. ':' or '=>' from TS); shell quoting mangling definition strings.","solutions":["Find the reported character in the echoed source string and remove or replace it with valid omptype syntax.","Replace smart quotes/unicode punctuation with ASCII equivalents (' instead of ').","Use '|' for unions and '&' for intersections instead of TS-style characters; consult the supported operator set (| & ( ) [ ] # % < <= > >= == = ? ,).","If the string is built dynamically, sanitize/validate the interpolated fragment before composing the definition."],"exampleFix":"// before\nschema.parse(\"string@\");\n// after\nschema.parse(\"string\"); // or \"string.email\" etc.","handlingStrategy":"validation","validationCode":"const ALLOWED = /^[\\w$.'\"\\/\\s|&()\\[\\]#%<>=?,+\\-:]/; // reject unknown chars up front\nif (/[“”‘’]/.test(def)) throw new Error(\"smart quotes in definition\");","typeGuard":null,"tryCatchPattern":"try {\n  const schema = parse(def);\n} catch (e) {\n  if (String(e.message).includes(\"unexpected character\")) {\n    // strip/replace the offending char and retry once\n  }\n  throw e;\n}","preventionTips":["Type definitions in an ASCII editor or lint for non-ASCII punctuation (smart quotes, en-dashes).","Keep a list of the supported operators (| & ( ) [ ] # % < <= > >= == = ?) handy when hand-writing definitions.","Sanitize user-supplied fragments before interpolating them into definition strings."],"tags":["parser","unexpected-character","schema-definition"],"backgroundTag":"invalid-type-syntax","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}