Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Diagnostics reference

Every diagnostic carries a stable code, SPX- plus a family letter and digits. Match on the code, not the message wording. The letter says which part of the toolchain refused your input.

error[SPX-U103]: `mut` is only allowed on local `let` bindings; parameters are immutable at u103.spx:4:6
  help: drop `mut` and copy the parameter into a new mutable local: `let mut current = <parameter>;`

The help: line is usually the fix. Fix the first diagnostic first; later ones often follow from it.

Look a code up

You wantCommand
The fix for a common mistakesemaprax help diagnostic SPX-T208 prints what you wrote and the fix
The list of codes with an indexed fixsemaprax help diagnostic codes (also bare semaprax help diagnostic)
Whether this compiler emits a codesemaprax explain SPX-T208 [--json] prints the family and how many places emit it
The exact grammar of a commandsemaprax help <command>
One diagnostic per line for toolsadd --json to check, build, run or test

help diagnostic indexes 24 codes, the mistakes people make most. For every other code, read the message and its help: line, then the spec for the feature. Codes are case-sensitive.

Common mistakes and fixes

Habits from other languages cause most first errors. The full habit table with runnable examples is in semaprax help language mistakes-code.

CodeYou wrote or hitFix
SPX-P0039223372036854775808 or -(9223372036854775808)Write the minimum as one literal: -9223372036854775808
SPX-P104struct, enum, pub, constrecord, variant; there is no visibility keyword
SPX-P105, SPX-P106return, else if, for i in 0..n, tuples, f(x);, a[0], fn f(), c ? a : b, break, as, a last field or arm without ,Use the tail expression, nested else { if ... }, while, a record, let _ = f(x);, byte_get(...), if; end every field and arm with ,
SPX-P130own fn with parametersAn owning closure takes none
SPX-P201x += 1, a Rust or JavaScript closurex = x + 1;; fn(x: i64) -> i64 { x + 1 }
SPX-P203A block with no final expressionEnd a while body with its continuation condition; end an if branch with a value
SPX-P207Nesting deeper than 128Extract a named helper
SPX-S103A declaration without @id (warning)Add @id("your.name"); semaprax fix --plan can plan it
SPX-S113Your own string_lenBuilt-in names are reserved; rename yours
SPX-T001, SPX-T281String, int, an unsupported Vec element typestring, i64, i32, u8, usize
SPX-T104fn main() -> boolExactly fn main() -> i64
SPX-T202, SPX-T203Some(1), None, s.len(), a method on a recordOption<i64>::Some { value: 1 }; string_len(s); only classes have methods
SPX-T205An owned value or literal where a borrow str goesBind it, then pass string_as_str(binding)
SPX-T207, SPX-T208index + 1 with a usize, or two different integer typesThe message names both types. Suffix the literal: index + 1usize
SPX-T209let x = x + 1; reusing a nameNo shadowing; pick a new name
SPX-T213A record literal missing a fieldName every field
SPX-T218f()? outside a Result functionmatch the result in main
SPX-T221, SPX-T225Option::Some { ... } to construct, or identity(4)Option<i64>::Some { ... }; identity<i64>(4). Matching omits the arguments.
SPX-T232let a: i32 = 55i32
SPX-T250"a" + "b", string_concat("n=", 5)string_concat(a, b); use string_from_i64(5) for numbers
SPX-T252, SPX-T258A record built in a while body or yielded from a match armCompute scalars in the loop and build after; or build with if
SPX-T257A scalar match with no catch-allAdd a final _ arm without a guard
SPX-T262[1, 2, 3]Array literals hold bytes ([1u8, 2u8]); use a Vec<i64> for numbers
SPX-T263, SPX-T266str_as_bytes(text) on an owned string, string_as_str("lit")let view = string_as_str(text); str_as_bytes(view); bind a literal first
SPX-T265, SPX-T267, SPX-T271, SPX-T272Buffer misuseNo live view across a replacement; bytes_zeroed outside loops; do not re-open a named buffer; keep the index in range
SPX-T270net_recv in a while bodyReceive outside the loop
SPX-T284A for over a let mut vectorMove the finished vector into an immutable binding first
SPX-T288, SPX-T291Nested generic-collection closures; owning closures in generic functionsName a helper; keep the closure out of the generic
SPX-O101Using a moved string or BytesThe callee takes borrow, or pass a fresh value or a copy
SPX-O116A function returning strReturn an owned string
SPX-U101Assigning an immutable bindinglet mut first
SPX-U103mut on a parameterCopy it into a new let mut local
SPX-E101, SPX-E102Missing permit or usespermit { ... } at module level, uses { ... } on the function and its callers. The message names both edits.
SPX-F102run refused to admit the programTry run --native, or build the project
SPX-G170use std::io;Built-ins need no import; import one declaration with use function @id("...") from module as name;
SPX-G174A rich type in a project function signatureKeep records module-local; cross boundaries with Copy scalars
SPX-B104run on a module with resourcecheck it, or run through a native or Wasm project build, or run <file> --native
SPX-J100Non-canonical manifestThe help names the first differing line
SPX-J120, SPX-J121, SPX-J122Unknown manifest key; bad dependency; target outside the matrixRemove or fix the key; bundled std.* at 0.1.0 with a satisfied range; build a listed target
SPX-J102A path alias given to a writing fmtUse the real path

An unknown function name that a project module or the standard library provides gets the exact use function @id("...") from ... as ...; line and, for the library, the dependency to add. A string_concat("n=", 5) or a wrong integer width names the fix.

Which part refused it?

LetterAreaWhere to read next
PParsing, plus size limits of reportsEssentials
S, JIdentities and declarations; manifestsManifests
T, O, U, E, M, NTypes, ownership, mutation, effects, matches, unsafe boundariesTypes, Ownership, Contracts and effects
KSession protocols (K1xx) and capability manifests (K2xx)semaprax help language (the full card)
F, B, HInterpreter admission, backends, replay of retained HIRTargets
GProjects, graphs, patches and workspaces: G409 stale patch, G530 stale revision, G150 wrong workspace kindShipping
IWorkspace, candidate and agent-runtime I/OAgent programs
WWasm and web export profiles (W115 signature outside the profile)Targets
A, D, X, Y, Q, VABI report, C header, C++ shim, hygienic generation, plugin manifest and verify front, SIMD reportIntegrations, Specialist commands
L, PKR, Z926, Z927Package locks, registry rules, registry readsShipping
Z70xRelease verification (Z701 shape, Z702 binding, Z703 identity, Z704 artifact, Z705 missing, Z707 cryptographic)Shipping
HP + letterHarness: HPB config and lock, HPD run pipeline, HPE context, HPJ routing, HPM skills, HPN bridgeHarness

Other families exist for specialist features (generic ownership, WIT, laws). semaprax explain <code> tells you if your compiler emits a code and which family it belongs to.

The debugging workflow around these codes (fmt first, fix the first diagnostic, read the help: line) is in Debugging.