Ubik
Operations

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.

CodeWhen
PARSE_ERRORThe SQL does not parse.
BIND_ERRORA column or function does not resolve: a TUMBLE over a non-timestamp column, window_start used in WHERE, an unknown column.
TYPE_ERRORA type mismatch in the query.
CONVERSION_ERRORA value does not cast, e.g. an integer epoch to TIMESTAMP (use epoch_ms).
OUT_OF_RANGEA value overflows its type.
NOT_SUPPORTEDA 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.

CodeWhen
DURABILITY_NOT_SUPPORTEDThe query uses an aggregate whose state cannot be checkpointed.
DETERMINISM_NOT_SUPPORTEDA non-deterministic construct that would not replay identically.

Source and sink

CodeWhen
INVALID_SOURCE / INVALID_SINKA malformed --from or --to URI.
SOURCE_ERRORThe source cannot be read: a missing topic, an unreadable file path, or the wrong bytes. The hint names which.
SINK_ERRORThe sink cannot be written.
SCHEMA_ERRORA schema cannot be inferred or resolved from the registry.
BROKER_LOSTA Kafka broker stayed unreachable past --broker-timeout.

Checkpoint and resume

CodeWhen
CHECKPOINT_EXISTSA 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_FAILEDThe checkpoint's directory fsync failed, so the write is reported failed rather than as a false commit.
CHECKPOINT_JOB_MISMATCHThe resumed run's SQL, source or options differ from the checkpoint's.
LOG_CHANGEDA file source's already-consumed bytes changed since the checkpoint.
DIMENSION_CHANGEDA 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.

CodeWhen
STATE_LOCKEDAnother engine is live on the state directory. Stop it first.
STATE_SPILL_FAILEDThe spill directory is full, read-only or gone. Point UBIK_SPILL_DIR at writable space.
STATE_KEY_TOO_WIDEOne GROUP BY key exceeds the block. Group by a narrower key.
STATE_VALUE_TOO_WIDEOne aggregated value exceeds the block. Bound a string_agg or list.
STATE_TOO_WIDEOne group's total aggregate state exceeds the block.
STATE_KEY_CORRUPTStored state did not decode: a damaged or incompatible checkpoint or spill file.

On this page