Error codes
85 codes
Every code the compiler puts on a diagnostic, read from its two registries at commit 26de7be8. The "use typeshade" front end has 47 codes and the core IR layer under it has 36.
49 pages carry a program that raises the code and the same program fixed. Both are compiled at build time against the pinned compiler, and the build stops when a program no longer raises its code or a fix no longer compiles clean. A row with an Example tag is one of them.
The registry text and every compiler message on these pages are the compiler's own English.
Front-end codes
The TS80xx codes, from TS_CODES in the front end. A "use typeshade" file is checked against these before any IR is built.
The file
-
TS8001MISSING_DIRECTIVEExample - A file compiled as TypeShade that has no
"use typeshade"directive at all. -
TS8013HOST_STMTExample - Host control flow and the JavaScript runtime forms no shader has:
await,yield, anasyncor generator function,try/catch/throw,for…in,var, a spread outside an object literal, and a template string. -
TS8014TOP_LEVELExample - Something at the top level of the file the compiler cannot declare: a bare statement, or a module-level declaration of a shape it refuses.
-
TS8030SYNTAXExample - A TypeScript parse error (an unclosed parenthesis, a missing brace, an unexpected token) in a
"use typeshade"file, carried through as a TypeShade diagnostic so acompile()caller sees it without runningtsc. -
TS8050ENABLE_NAMEExample - A file-level
"enable <extension>";directive (§50) naming an extension outside the vocabulary the WGSL backend's capability profile carries a directive for (clip_distances,dual_source_blending,f16,primitive_index,subgroups). -
TS8072IMPORTExample - An import the compiler does not follow (Rule 3.9, surface §68, proposals 0022 and 0024): a path that names no file or one this compile cannot read, a file that is not a shader module, a package no
node_modulesholds, a subpath a package'sexportsdoes not name, a package's name alone when it has noexports, a#specifier or one that is neither relative nor a package name, a name the module does not export, and the forms a shader module has no use for (a default import or export, an import that names nothing,import(...),require, a module namespace used as a value). -
TS8099UNSUPPORTEDExample UNSUPPORTED(TS8099) is the one deliberate exception to "sequential": it is the catch-all for a diagnostic whose site does not yet deserve its own code, so it stays parked past the sequential range instead of at its head.
Types and names
-
TS8002UNKNOWN_TYPEExample - A type name nothing declares, said once for the file wherever it is written (a parameter, a claim, a type argument,
B<vec3<Foo>>included, an alias, animplementsclause, the base a class or an interface extends, a body no call lowers), a type the library declares for TypeScript alone (Number) where the file declares none of its name, or a type this surface does not take in a position the mapper reads (Rule 2.1). -
TS8003TYPE_MISMATCHExample - Two types that do not fit where they meet (an operator, a condition, a declaration, a return or an argument), or a constant the compiler folds that WGSL refuses: a shift amount past 31, a divisor of 0, clamp bounds that cross or an f32 past its range.
-
TS8005CONST_ASSIGNExample - An assignment to a name that cannot change, such as a
constor a read-only resource. -
TS8010STRUCT_FIELDExample - An invalid struct field or declaration shape.
-
TS8016INDEX_OOBExample - A constant index outside the length of what it indexes.
-
TS8018ASSIGN_TARGETExample - An assignment or
++/--target that is not a writable place, such as a temporary or an input that has no writable value local. -
TS8022UNKNOWN_NAMEExample - Reference to a name TypeShade cannot resolve (identifier, struct field, or struct shape) that is not a function call (
UNKNOWN_FN) or a type name (UNKNOWN_TYPE), in a body a call lowers or in one no call lowers; a name the library declares for TypeScript's own use (Object,Math,Symbol), or the file declares as an enum, a namespace, a class or a type, read as a value says what it is. -
TS8023DUPLICATE_SYMBOLExample - The same function, binding, module constant or struct name declared twice in one scope.
-
TS8053INT_LITERAL_DEPRECATIONExample - A deprecation warning, not an error: an undecided integer-written declaration still defaults to
f32and will default toi32(§13).
Functions and classes
-
TS8004UNKNOWN_FNExample - A call to a function the file neither declares nor imports.
-
TS8019ARITY_MISMATCHExample - Wrong number of arguments, elements, or fields at a call or constructor site.
-
TS8020FUNCTION_SHAPEExample - A function declaration or parameter shape TypeShade does not support (missing name or body, optional/rest/destructured parameter).
-
TS8021RETURN_SHAPEExample - A
returnshape problem: barereturnwhere a value is required, or an entry function with no return type annotation that returns a value. -
TS8031RECURSIONExample - A call cycle: a function that reaches itself, directly or through other functions.
-
TS8035CLASS_MEMBERExample - A class member shape the surface does not take, or a use of a member the class rules refuse, and a
newthat builds no class (Rule 8.13). -
TS8036MATH_ARGUMENTExample - A math builtin called with arguments its signature does not take: two shapes that had to agree (
dot(vec3, vec2),clamp(v, 0., 1.)with a vectorv), an element kind the builtin has no form for (sinon an integer vector,mixon one), a scalar where a vector is due (normalize(s),crosson avec2),mix's factor orrefract's eta of the wrong shape,ldexp's exponent not an i32 ofx's shape, a bit offset or count that is not au32, ortranspose/determinanton a non-matrix.
Control flow
-
TS8006LOOP_BOUNDExample - A counted
forloop whose exit the compiler cannot prove: the counter is not compared to a bound, or the body writes the bound. -
TS8007LOOP_INFINITEExample - A loop that certainly never ends: a
whilewhose condition istrue, written or folded from constants, with nobreakorreturn, or a step that moves the counter away from its bound. -
TS8008LOOP_INDUCTIONExample - A
forloop whose counter is not oneletof typei32oru32, or whose update is not a constant step. -
TS8009BREAK_OUTSIDEExample - A
breakwith no loop orswitcharound it. -
TS8017SWITCH_CASEExample - Invalid
switchcase: a label that is not an integer constant, does not fit the selector, or repeats another; an empty clause with no body below it to share (a trailing one, or one abovedefault:); a body whose end is reachable above a clause with a body, which TypeScript would run on into and WGSL does not (Rule 7.3); orcontinuein a switch no loop encloses. -
TS8034BARRIER_PLACEMENTExample workgroupBarrier()/storageBarrier()somewhere a barrier cannot stand (§25): in a vertex or fragment entry, which has no workgroup; or as a value, since a barrier is a statement (roadmap 0.2 item 5).-
TS8052UNIFORMITYExample - A call that needs uniform control flow —
textureSampleand the other implicit-LOD forms, the derivatives, a barrier, orworkgroupUniformLoad— reached under a condition that is not uniform across the invocations that run together (anif, aswitch, a loop's condition, the left side of&&or||, the condition of a?:WGSL writes as anif), or after areturn,breakorcontinuetaken under one (§54).
Entry points and IO
-
TS8024BUILTIN_NAMEExample @builtin("...")names an id outside WGSL's builtin vocabulary (WgslBuiltinNameincore/sot.ts).-
TS8025BUILTIN_STAGEExample - A
@builtin(...)id used as the wrong stage's input or output, e.g.frag_depthon a vertex return, orfront_facingon a vertex parameter. -
TS8026WORKGROUP_SHAPEExample - A warning:
@compute([x, y, z])exceeds one of WebGPU's default compute limits (xandy256,z64, 256 invocations in all), so a device requested without raising that limit refuses the pipeline. -
TS8028ATTRIBUTE_NAMEExample - A decorator identifier outside the attribute vocabulary
"use typeshade"defines (@vertex,@fragment,@compute,@builtin,@location), e.g. a misspelled@vertx: without this, the decorated function or field just silently stops being an entry point or an I/O field. -
TS8029STRUCT_FIELD_MISSING_ATTRExample - A field of a struct used as an entry function's parameter or return type carries neither
@builtin(...)nor@location(...): WGSL rejects an entry-IO struct member with no attribute, so this is caught at the front end instead of reaching the backend as invalid emitted WGSL. -
TS8037WORKGROUP_ARGExample @compute(...)with an argument that is not an array literal of one to three whole numbers: an object, a bare number, an identifier, an empty or four-wide array.
Resources and memory
-
TS8032UNSIZED_ARRAY_LENGTHExample .length, orarrayLength(x), on anarray<T>with noNthat is not in storage: auniform<array<T>>, a local, or a parameter.-
TS8033MODULE_VARExample - A module variable (
let x: workgroup<T>,let y: T = init, §24) declared or used where its address space forbids: aconstwith an address-space wrapper, aworkgroupvariable with an initializer, a type the space cannot hold (a texture, a runtime-sized array, an atomic in a per-invocation variable), an initializer that is not a constant, or aworkgroupvariable reached from a vertex or fragment entry (roadmap 0.2 item 5). -
TS8041TEXTURE_ARGUMENTExample - A plain argument of a texture read that the target has no overload for: a coordinate or gradient of the wrong width for the texture's dim or of an element kind the read does not take (a sampled read is by normalised
f32, a texel fetch by wholei32/u32texel), a layer, mip level or sample index that is not an integer or is not a whole number of 0 or more, and alevel,biasordepth_refthat is not anf32. -
TS8051LAYOUTExample - A buffer binding's store type breaks one of WGSL's host-shareable rules (§51), which a struct hides from the type map and the backend only meets as emitted text: a
bool, alone or in a vector, in auniformorstoragebinding, as a field, a runtime array's element or the whole type (type 'bool' cannot be used in address space 'uniform' as it is non-host-shareable, and the same ofvec3<bool>), a runtime-sizedarray<T>that is not its struct's last member, or a runtime-sized array in a uniform, whose type must be constructible.
Emulated double
-
TS8027MAT_UNSUPPORTEDExample - A non-square
matCxR<f64>: the fp64 pass carries one df64 body per dimension (DF64MatN, matmul, matvec, transpose), so only a square matrix of doubles lowers. -
TS8038F64_ENTRY_IOExample - An emulated double (
f64, avec64) on an entry's IO boundary — a@locationparameter, a@locationfield of an IO struct, or an entry's return.
Targets
-
TS8015BACKENDExample - A backend that refused to emit a module the front end accepted. The message is the backend's own.
-
TS8068RESERVED_NAMEExample - A declared name that a target reserves, checked on the name the emit actually carries:
halfas a struct field, which ANGLE answers with "Illegal use of reserved word" in generated text the author never wrote.
Retired numbers
-
TS8011 - A gap (8011 and 8012 are retired) is never reused.
-
TS8012 - A gap (8011 and 8012 are retired) is never reused.
Other codes
-
TS8069MISPLACED_DIRECTIVEExample - A
"use typeshade"directive after another top-level statement (Rule 3.1). -
TS8070KERNEL_LOOP_ON_CPU - A warning on a loop of a kernel function (Rule 8.22, surface §65, proposal 0013) that the independence proof refused: the loop runs on the CPU, and the message names the line and the author's names that stop it, and the remedy.
-
TS8071CONSOLE_NOT_RECORDEDExample - A warning under
compile(src, { console: 'gpu' }): aconsolecall the WGSL does not record, on the call, with the reason (a vertex entry reaches it, an argument has no fixed size or is not a value, the stage has no room for another storage buffer).
Core codes
The SDxxxx codes, from the CODES catalogue in typeshade/dev. The core IR layer raises them under the fn() builder and under a "use typeshade" file alike, and the front end refuses many of the same mistakes first under a code of its own.
Types and names
-
SD0001 - matrix × vector size mismatch
-
SD0002 - binary op on mismatched vectors
-
SD0003 - arithmetic op on a bool operand
-
SD0004 - binary op on incompatible types
-
SD0005 - bitwise op requires a u32/i32 left operand
-
SD0006 - component access on a non-vector
-
SD0007 - vector component out of range
-
SD0008 - swizzle on a non-vector
-
SD0009 - .select() on a non-bool condition
-
SD0010 - select branches have differing types
-
SD0011 - matchExpr case type does not match the default
-
SD0015 - array-texture layer must be an integer
-
SD0116 - a scalar cast applied to a non-scalar value
-
SD0117 - a one-argument .at(i) on a node that is not an array
Builder calls
-
SD0012 - statement sink not installed
-
SD0013 - no active builder
-
SD0113 - a fn whose body returns nothing at the TypeScript level returns a value at run time
-
SD0115 - a branch body returned a value, which a branch cannot carry out
Resources and memory
-
SD0014 - override (specialization constant) must be a WGSL scalar type
-
SD0016 - host-owned resource has a shape the target cannot spell
-
SD0114 - a variable a function reads has no declaration in the module
Targets
-
SD0017 - literal cannot be spelled by the target
-
SD0020 - module validation failed
-
SD0030Example - unsupported feature for this backend
Emulated double
-
SD0040 - f64 type leaked past fp64Lower into a backend emitter
-
SD0041 - unsupported operation on f64 operands
-
SD0042 - conflicting fp64 guard declaration
-
SD0043Example - reserved fp64 name
-
SD0044 - f64 in an interpolated @location IO field
Lint rules
-
SD0107 - assignment to an immutable 'let' binding
-
SD0108Example - smoothstep with constant edge0 >= edge1 (undefined in GLSL ES)
-
SD0109 - a fragment-only builtin is reachable from a vertex or compute entry
-
SD0112 - a local name is declared twice in one function
Portable kernels
Other codes
-
SD0118 - grad cannot differentiate this function
Numbering
The front end's registry explains its numbers in its own header:
Numbering: TS8 + a zero-padded sequential number, assigned in the order a code was added. A gap (8011 and 8012 are retired) is never reused. UNSUPPORTED (TS8099) is the one deliberate exception to "sequential": it is the catch-all for a diagnostic whose site does not yet deserve its own code, so it stays parked past the sequential range instead of at its head.
One more kind of gap exists from TS8039 to TS8067. While several sessions worked the issue list of #162 in parallel, each was given a BLOCK of codes to draw from, so two branches in flight at once could not claim one number twice. F64_ENTRY_IO (TS8038) is the last code in the sequential range; TEXTURE_ARGUMENT (TS8041) and RESERVED_NAME (TS8068) were assigned from blocks, and the numbers a block did not spend stay unspent. A block's unused codes stay unused, exactly as 8011 does — a gap is never reused.
Implements: Rule 3.7 (docs/language-design.md; traced in reqs/).