Error codes
On this page

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

TS8001 MISSING_DIRECTIVE Example
A file compiled as TypeShade that has no "use typeshade" directive at all.
TS8013 HOST_STMT Example
Host control flow and the JavaScript runtime forms no shader has: await, yield, an async or generator function, try/catch/throw, for…in, var, a spread outside an object literal, and a template string.
TS8014 TOP_LEVEL Example
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.
TS8030 SYNTAX Example
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 a compile() caller sees it without running tsc.
TS8050 ENABLE_NAME Example
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).
TS8072 IMPORT Example
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_modules holds, a subpath a package's exports does not name, a package's name alone when it has no exports, 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).
TS8099 UNSUPPORTED Example
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

TS8002 UNKNOWN_TYPE Example
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, an implements clause, 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).
TS8003 TYPE_MISMATCH Example
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.
TS8005 CONST_ASSIGN Example
An assignment to a name that cannot change, such as a const or a read-only resource.
TS8010 STRUCT_FIELD Example
An invalid struct field or declaration shape.
TS8016 INDEX_OOB Example
A constant index outside the length of what it indexes.
TS8018 ASSIGN_TARGET Example
An assignment or ++/-- target that is not a writable place, such as a temporary or an input that has no writable value local.
TS8022 UNKNOWN_NAME Example
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.
TS8023 DUPLICATE_SYMBOL Example
The same function, binding, module constant or struct name declared twice in one scope.
TS8053 INT_LITERAL_DEPRECATION Example
A deprecation warning, not an error: an undecided integer-written declaration still defaults to f32 and will default to i32 (§13).

Functions and classes

TS8004 UNKNOWN_FN Example
A call to a function the file neither declares nor imports.
TS8019 ARITY_MISMATCH Example
Wrong number of arguments, elements, or fields at a call or constructor site.
TS8020 FUNCTION_SHAPE Example
A function declaration or parameter shape TypeShade does not support (missing name or body, optional/rest/destructured parameter).
TS8021 RETURN_SHAPE Example
A return shape problem: bare return where a value is required, or an entry function with no return type annotation that returns a value.
TS8031 RECURSION Example
A call cycle: a function that reaches itself, directly or through other functions.
TS8035 CLASS_MEMBER Example
A class member shape the surface does not take, or a use of a member the class rules refuse, and a new that builds no class (Rule 8.13).
TS8036 MATH_ARGUMENT Example
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 vector v), an element kind the builtin has no form for (sin on an integer vector, mix on one), a scalar where a vector is due (normalize(s), cross on a vec2), mix's factor or refract's eta of the wrong shape, ldexp's exponent not an i32 of x's shape, a bit offset or count that is not a u32, or transpose/determinant on a non-matrix.

Control flow

TS8006 LOOP_BOUND Example
A counted for loop whose exit the compiler cannot prove: the counter is not compared to a bound, or the body writes the bound.
TS8007 LOOP_INFINITE Example
A loop that certainly never ends: a while whose condition is true, written or folded from constants, with no break or return, or a step that moves the counter away from its bound.
TS8008 LOOP_INDUCTION Example
A for loop whose counter is not one let of type i32 or u32, or whose update is not a constant step.
TS8009 BREAK_OUTSIDE Example
A break with no loop or switch around it.
TS8017 SWITCH_CASE Example
Invalid switch case: 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 above default:); 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); or continue in a switch no loop encloses.
TS8034 BARRIER_PLACEMENT Example
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).
TS8052 UNIFORMITY Example
A call that needs uniform control flow — textureSample and the other implicit-LOD forms, the derivatives, a barrier, or workgroupUniformLoad — reached under a condition that is not uniform across the invocations that run together (an if, a switch, a loop's condition, the left side of && or ||, the condition of a ?: WGSL writes as an if), or after a return, break or continue taken under one (§54).

Entry points and IO

TS8024 BUILTIN_NAME Example
@builtin("...") names an id outside WGSL's builtin vocabulary (WgslBuiltinName in core/sot.ts).
TS8025 BUILTIN_STAGE Example
A @builtin(...) id used as the wrong stage's input or output, e.g. frag_depth on a vertex return, or front_facing on a vertex parameter.
TS8026 WORKGROUP_SHAPE Example
A warning: @compute([x, y, z]) exceeds one of WebGPU's default compute limits (x and y 256, z 64, 256 invocations in all), so a device requested without raising that limit refuses the pipeline.
TS8028 ATTRIBUTE_NAME Example
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.
TS8029 STRUCT_FIELD_MISSING_ATTR Example
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.
TS8037 WORKGROUP_ARG Example
@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

TS8032 UNSIZED_ARRAY_LENGTH Example
.length, or arrayLength(x), on an array<T> with no N that is not in storage: a uniform<array<T>>, a local, or a parameter.
TS8033 MODULE_VAR Example
A module variable (let x: workgroup<T>, let y: T = init, §24) declared or used where its address space forbids: a const with an address-space wrapper, a workgroup variable 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 a workgroup variable reached from a vertex or fragment entry (roadmap 0.2 item 5).
TS8041 TEXTURE_ARGUMENT Example
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 whole i32/u32 texel), a layer, mip level or sample index that is not an integer or is not a whole number of 0 or more, and a level, bias or depth_ref that is not an f32.
TS8051 LAYOUT Example
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 a uniform or storage binding, 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 of vec3<bool>), a runtime-sized array<T> that is not its struct's last member, or a runtime-sized array in a uniform, whose type must be constructible.

Emulated double

TS8027 MAT_UNSUPPORTED Example
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.
TS8038 F64_ENTRY_IO Example
An emulated double (f64, a vec64) on an entry's IO boundary — a @location parameter, a @location field of an IO struct, or an entry's return.

Targets

TS8015 BACKEND Example
A backend that refused to emit a module the front end accepted. The message is the backend's own.
TS8068 RESERVED_NAME Example
A declared name that a target reserves, checked on the name the emit actually carries: half as 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

TS8069 MISPLACED_DIRECTIVE Example
A "use typeshade" directive after another top-level statement (Rule 3.1).
TS8070 KERNEL_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.
TS8071 CONSOLE_NOT_RECORDED Example
A warning under compile(src, { console: 'gpu' }): a console call 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
SD0030 Example
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
SD0043 Example
reserved fp64 name
SD0044
f64 in an interpolated @location IO field

Lint rules

SD0107
assignment to an immutable 'let' binding
SD0108 Example
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

SD0110
portable declared on a non-compute entry
SD0111
portable kernel outside the gather-only tier

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/).

Edit this page Report a problem