Errors
The coded error envelope, code, message and hint, and the catalog of codes grouped by when they fire.
Every failure is one envelope: a machine code in SCREAMING_SNAKE_CASE, a
human message, and an actionable hint. The same triple reaches the CLI on
stderr, ubik_last_error in C, and UbikError (.code, .message, .hint)
in Python, so an error read in a notebook reads identically in a pipeline log.
{"error":{"code":"BIND_ERROR","message":"the TUMBLE/HOP time argument must be a TIMESTAMP column","hint":"Cast a string column, e.g. TUMBLE(CAST(ts AS TIMESTAMP), INTERVAL 1 MINUTE); convert an integer epoch with epoch_ms(ts) for milliseconds or epoch_ms(ts * 1000) for seconds."}}Every error carries a hint that says what to do. A query that fails to parse or bind comes back under a ubik code, not DuckDB's: DuckDB's internal error surface is a private detail and never reaches the message.
Query, at plan time
Caught before the first row, so the error names the mistake, not the row it happened to touch.
| Code | When |
|---|---|
PARSE_ERROR | The SQL does not parse. |
BIND_ERROR | A column or function does not resolve: a TUMBLE over a non-timestamp column, window_start used in WHERE, an unknown column. |
TYPE_ERROR | A type mismatch in the query. |
CONVERSION_ERROR | A value does not cast, e.g. an integer epoch to TIMESTAMP (use epoch_ms). |
OUT_OF_RANGE | A value overflows its type. |
NOT_SUPPORTED | A construct ubik does not support: a bare-number window interval, an order-dependent aggregate over HOP. |
Streaming semantics
Refused at plan time, because they would break exactly-once on a stream.
| Code | When |
|---|---|
DURABILITY_NOT_SUPPORTED | The query uses an aggregate whose state cannot be checkpointed. |
DETERMINISM_NOT_SUPPORTED | A non-deterministic construct that would not replay identically. |
Source and sink
| Code | When |
|---|---|
INVALID_SOURCE / INVALID_SINK | A malformed --from or --to URI. |
SOURCE_ERROR | The source cannot be read: a missing topic, an unreadable file path, or the wrong bytes. The hint names which. |
SINK_ERROR | The sink cannot be written. |
SCHEMA_ERROR | A schema cannot be inferred or resolved from the registry. |
BROKER_LOST | A Kafka broker stayed unreachable past --broker-timeout. |
Checkpoint and resume
| Code | When |
|---|---|
CHECKPOINT_EXISTS | A fresh run would overwrite an existing checkpoint. Resume it, or choose another path. |
CHECKPOINT_READ_FAILED | --resume points at no checkpoint, or a damaged or incompatible one. |
CHECKPOINT_WRITE_FAILED | The checkpoint's directory fsync failed, so the write is reported failed rather than as a false commit. |
CHECKPOINT_JOB_MISMATCH | The resumed run's SQL, source or options differ from the checkpoint's. |
LOG_CHANGED | A file source's already-consumed bytes changed since the checkpoint. |
DIMENSION_CHANGED | A bounded join dimension drifted from the version pinned at checkpoint time. |
State
The aggregate state codec caps a single group at a 256 KiB block.
| Code | When |
|---|---|
STATE_LOCKED | Another engine is live on the state directory. Stop it first. |
STATE_SPILL_FAILED | The spill directory is full, read-only or gone. Point UBIK_SPILL_DIR at writable space. |
STATE_KEY_TOO_WIDE | One GROUP BY key exceeds the block. Group by a narrower key. |
STATE_VALUE_TOO_WIDE | One aggregated value exceeds the block. Bound a string_agg or list. |
STATE_TOO_WIDE | One group's total aggregate state exceeds the block. |
STATE_KEY_CORRUPT | Stored state did not decode: a damaged or incompatible checkpoint or spill file. |