{"record":{"id":"2ffe93a76301ef3b","repo":"can1357/oh-my-pi","slug":"trailing-tokens-in-definition-this-src","errorCode":null,"errorMessage":"trailing tokens in definition \"${this.#src}\"","messagePattern":"trailing tokens in definition \"(.+?)\"","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/ir.ts","lineNumber":386,"sourceCode":"\t\tlet def: unknown;\n\t\tlet hasDefault = false;\n\t\tif (this.#eatOp(\"=\")) {\n\t\t\tconst t = this.#next();\n\t\t\tif (t.t === \"num\" || t.t === \"bigint\" || t.t === \"date\" || t.t === \"str\") def = t.v;\n\t\t\telse if (t.t === \"id\" && (t.v === \"true\" || t.v === \"false\")) def = t.v === \"true\";\n\t\t\telse if (t.t === \"id\" && t.v === \"null\") def = null;\n\t\t\telse if (t.t === \"id\" && t.v === \"undefined\") def = undefined;\n\t\t\telse throw new OmpTypeError(`unsupported default literal in \"${this.#src}\"`);\n\t\t\thasDefault = true;\n\t\t}\n\t\tconst optional = this.#eatOp(\"?\");\n\t\tthis.#expectEnd();\n\t\treturn { ir, def, hasDefault, optional };\n\t}\n\n\t#expectEnd(): void {\n\t\tif (this.#pos < this.#toks.length) {\n\t\t\tthrow new OmpTypeError(`trailing tokens in definition \"${this.#src}\"`);\n\t\t}\n\t}\n\n\tparseUnion(): IR {\n\t\tconst first = this.parseIntersection();\n\t\tif (!this.#eatOp(\"|\")) return first;\n\t\tconst members = [first, this.parseIntersection()];\n\t\twhile (this.#eatOp(\"|\")) members.push(this.parseIntersection());\n\t\treturn { k: \"union\", members };\n\t}\n\n\tparseIntersection(): IR {\n\t\tconst first = this.parseBounded();\n\t\tif (!this.#eatOp(\"&\")) return first;\n\t\tconst members = [first, this.parseBounded()];\n\t\twhile (this.#eatOp(\"&\")) members.push(this.parseBounded());\n\t\tconst literal = members.find((member): member is Extract<IR, { k: \"lit\" }> => member.k === \"lit\");\n\t\tif (literal && typeof literal.v === \"number\") {","sourceCodeStart":368,"sourceCodeEnd":404,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/ir.ts#L368-L404","documentation":"After parsing a complete definition (union, optional '?', default), #expectEnd found leftover tokens. The string is grammatically valid up to a point but continues with content the top-level grammar doesn't accept — a full definition must consume the entire token stream.","triggerScenarios":"'string string' (two keywords), 'number 5', 'string[] number', stray commas/semicolons ('string,'), 'number>=1 2', or an extra '?'/'?' after content that parseTop already handled.","commonSituations":"Concatenating multiple definitions with a space instead of '|' ('string number' vs 'string | number'); leftover separator characters when joining definitions programmatically; typos where a comma was used instead of '|' in object properties.","solutions":["Join alternatives with '|' ('string | number'), not whitespace.","Remove stray separators (commas, semicolons, spaces) that aren't part of the grammar.","If multiple properties are intended, wrap them in object syntax '{ key: value, ... }' rather than listing definitions sequentially.","Read the echoed source in the message; everything after the valid definition is the offending tail."],"exampleFix":"// before\nschema.parse(\"string number\");\n// after\nschema.parse(\"string | number\");","handlingStrategy":"validation","validationCode":"// tokenize-like sanity: no two adjacent keywords without a separator\nif (/\\b(string|number|boolean|bigint)\\s+(string|number|boolean|bigint)\\b/.test(def)) {\n  throw new Error(`missing '|' between types: ${def}`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const schema = parse(def);\n} catch (e) {\n  if (String(e.message).includes(\"trailing tokens\")) {\n    // inspect everything after the first valid type; join with '|' or remove\n  }\n  throw e;\n}","preventionTips":["Separate union members with '|', never whitespace or commas.","When joining definitions programmatically, use an explicit separator and trim stray commas/semicolons.","Put multi-property schemas in object syntax '{ ... }'."],"tags":["parser","trailing-tokens","schema-definition"],"backgroundTag":"invalid-type-syntax","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}