---
audience: engineers
summary: The Exxx diagnostic codes the ScaiCore compiler emits, grouped by phase,
  with the most common fixes.
title: Compile errors
path: troubleshooting/compile-errors
status: published
---

The compiler emits diagnostics with a stable `Exxx` code identifying the phase and the specific check. The first digit is the phase: `0` lexer, `1` parser, `2` name resolution, `3` type checking, `4` verifier. Every diagnostic carries a source location and a human-readable message. The list below covers the common ones and what they usually mean.

## Lexer (E0xx)

These fire before any structure is recognized — the source isn't even tokens yet.

| Code | Symptom | Common cause |
|---|---|---|
| `E001` | Unexpected character | A stray byte the lexer doesn't recognize. Check for smart-quotes pasted from a doc. |
| `E002` | Unterminated string | A `"` without a matching close. Multi-line strings need explicit escapes. |
| `E003` | Unterminated comment | A `/*` without a closing `*/`. |
| `E004` | Invalid escape sequence | An unknown `\x` inside a string literal. |
| `E005` | Invalid numeric literal | Trailing alpha after digits, or a number that doesn't parse. |
| `E006` | Reserved keyword | A reserved word used as an identifier. Rename the binding. |
| `E007` | Unknown `@`-keyword | An `@something` the compiler doesn't recognize. Check the spelling against the language dictionary. |
| `E008` | Unterminated string interpolation | `${` without a matching `}` inside a string. |

## Parser (E1xx)

The token stream didn't match the grammar.

| Code | Symptom | Common cause |
|---|---|---|
| `E100` | Unexpected token | A token where the grammar expected something else — often a stray `,` or missing `=`. |
| `E101` | Expected specific token | The grammar required a particular token (e.g. `}`) and got something else. |
| `E102` | Expected expression | A spot that needs an expression got a statement or punctuation. |
| `E103` | Expected type | A type annotation slot got a non-type. |
| `E104` | Expected block | A `{ … }` block was expected (often after `@flow` or `@rigid`). |
| `E105` | Expected identifier | A name was expected (parameter, field, etc.). |
| `E106` | Invalid pattern | A `@match` arm has an unrecognized pattern shape. |
| `E107` | Expected core declaration | The file's first top-level construct must be `@core`. |
| `E108` | Duplicate field | A struct or block has the same field name twice. |

## Name resolution (E2xx)

The grammar parsed, but a reference points to something that isn't defined.

| Code | Symptom | Common cause |
|---|---|---|
| `E200` | Undefined name | A variable is referenced before it's bound. |
| `E201` | Duplicate name | Two declarations of the same name at the same scope. |
| `E202` | Undefined type | A type annotation references a type that doesn't exist. Check spelling and that the `type` declaration came first. |
| `E203` | Unresolved import | An `import` couldn't locate its target. |
| `E204` | Undefined flow | A `@core_call` or call references a flow that isn't declared. |
| `E205` | Undefined plugin | A plugin call references a plugin not declared in `@plugins`. |
| `E206` | Undefined model | A `@flexible` or `@model_call` references an LLM role not declared in `@llm`. |

## Type checking (E3xx)

Names resolved but types don't line up.

| Code | Symptom | Common cause |
|---|---|---|
| `E300` | Type mismatch | A value's inferred type doesn't match the expected type at its use site. |
| `E301` | Incompatible operands | An operator was applied to operands of incompatible types (`"x" + 1`, etc.). |
| `E302` | Wrong argument count | A call has too many or too few arguments. |
| `E303` | Wrong argument type | A call's argument doesn't match the parameter's declared type. |
| `E304` | Missing return | A flow declared to return a value has a path that doesn't return. |
| `E305` | Void return value | A flow declared `void` returns a value. |
| `E306` | Memory type mismatch | A `memory.<key> = value` writes a type the schema doesn't allow. |
| `E307` | Forbidden `Any` type | An `Any` type leaked into a position where a specific type is required. |

## Verifier (E4xx)

Types pass but the program violates a runtime invariant that's checkable statically.

| Code | Symptom | Common cause |
|---|---|---|
| `E400` | Rigid non-determinism | A `@rigid` block contains a non-deterministic operation. Rigid blocks must be replayable. |
| `E401` | Internal flow reachable | An `@internal` flow is reachable from a public surface. Mark it `pub` or restructure callers. |
| `E402` | Entity key missing | An `entity`-instance Core declares `entity_key` but never produces it. |
| `E403` | Checkpoint inside `@parallel` | A `@checkpoint` is nested inside a `@parallel` branch. Suspend/resume across parallel branches isn't supported. |
| `E404` | Emit schema mismatch | An `emit` event's payload doesn't match the declared event schema in the manifest. |
| `E405` | LLM call inside `@rigid` | A `@flexible` or `@model_call` is nested inside a `@rigid` block. LLM calls aren't allowed in rigid context. |

## Tips

- Pass `--strict` to `scaicore check` and `scaicore compile` to elevate warnings to errors. Useful in CI.
- A diagnostic's source location pinpoints the *immediate* cause; if it's confusing, scan one or two declarations earlier — a missing comma or brace cascades into several downstream complaints.
- For verifier errors specifically, the message often suggests the structural change (e.g. "move the @checkpoint outside the @parallel block"). Read the full message before refactoring.
