{"record":{"id":"e5121bc9d4a2b2ea","repo":"can1357/oh-my-pi","slug":"literal-is-excluded-by-intersection","errorCode":null,"errorMessage":"literal is excluded by intersection","messagePattern":"literal is excluded by intersection","errorType":"exception","errorClass":"OmpTypeError","httpStatus":null,"severity":"error","filePath":"packages/omptype/src/ir.ts","lineNumber":413,"sourceCode":"\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\") {\n\t\t\tfor (const member of members) {\n\t\t\t\tif (\n\t\t\t\t\tmember.k === \"number\" &&\n\t\t\t\t\t((member.int && !Number.isInteger(literal.v)) ||\n\t\t\t\t\t\t(member.divisor !== undefined && literal.v % member.divisor !== 0) ||\n\t\t\t\t\t\t(member.min !== undefined && (member.xmin ? literal.v <= member.min : literal.v < member.min)) ||\n\t\t\t\t\t\t(member.max !== undefined && (member.xmax ? literal.v >= member.max : literal.v > member.max)))\n\t\t\t\t) {\n\t\t\t\t\tthrow new OmpTypeError(\"literal is excluded by intersection\");\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn literal;\n\t\t}\n\t\treturn { k: \"intersection\", members };\n\t}\n\n\t/**\n\t * `NUM CMP base (CMP NUM)?` or `base (CMP NUM)?`, with `[]*` postfix on the\n\t * base AND after a trailing bound — `string>0[]` is an array of bounded\n\t * strings, matching ArkType precedence (bounds bind tighter than `[]`).\n\t */\n\tparseBounded(): IR {\n\t\tconst t = this.#peek();\n\t\tconst t1 = this.#peek(1);\n\t\tif ((t?.t === \"num\" || t?.t === \"date\") && t1?.t === \"op\" && (t1.v === \"<\" || t1.v === \"<=\")) {\n\t\t\tconst lo = t.v;\n\t\t\tthis.#pos += 2;","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/omptype/src/ir.ts#L395-L431","documentation":"parseIntersection detected a numeric literal intersected with a number constraint it cannot satisfy: integer-ness, a % divisor, or a min/max bound. E.g. '2.5 & number.integer', '3 & number % 2', '0 & number > 1'. The result would be the never type, so the library refuses at parse time rather than producing a schema that matches nothing.","triggerScenarios":"Intersections of a number literal with 'number.integer' when the literal has a fraction; with a '% n' divisor when literal % n !== 0; or with a bound (>, >=, <, <=, possibly flipped via the left-bound form) that excludes the literal.","commonSituations":"Combining a constant with a refinement written by a different code path (template-built constraints drifting out of sync with the literal); refactoring bounds without updating co-declared literals; generically composing 'value & number >= minValue' where value < minValue.","solutions":["Make the literal satisfy the constraint: use an integer for '& number.integer', a multiple for '% n', and a value inside the bounds.","If the constant was meant to be independent, replace '&' with a union '|' or remove the redundant constraint.","Recompute bounds/divisor so they're consistent with the literal, ideally deriving both from one source constant.","If never is genuinely intended, use the explicit 'never' keyword instead of a contradictory intersection."],"exampleFix":"// before\nschema.parse(\"3 & number % 2\"); // never\n// after\nschema.parse(\"3 & number % 1\"); // or just 3, or 4 & number % 2","handlingStrategy":"validation","validationCode":"function literalFits(v, { int, divisor, min, max, xmin, xmax }) {\n  if (int && !Number.isInteger(v)) return false;\n  if (divisor !== undefined && v % divisor !== 0) return false;\n  if (min !== undefined && (xmin ? v <= min : v < min)) return false;\n  if (max !== undefined && (xmax ? v >= max : v > max)) return false;\n  return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n  const schema = parse(def);\n} catch (e) {\n  if (String(e.message) === \"literal is excluded by intersection\") {\n    // drop the conflicting constraint or correct the literal\n  }\n  throw e;\n}","preventionTips":["Derive literals and their constraints from the same source constant so they can't drift.","Check divisibility/integer-ness of constants before intersecting them with refined number types.","Use 'never' explicitly if an empty type is intended."],"tags":["parser","intersection","unsatisfiable-constraint"],"backgroundTag":"unsatisfiable-type-intersection","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}