-

Please Enter Your Search
search icon
Nothing found for your search
Search results from other manuals
Nothing found for your search

1 Cancel and errors

Two things a driving integration has to handle: stopping a run that should not continue, and reacting when the machine reports a problem. They interact, so they are together.

1.1 Cancel is two steps

Canceling takes a lease first, then commits it:

curl --insecure -b cookies.txt https://kilobaser.lab.example.org/api/control/cancel
{
  "currentState": { "mode": "emergencyStop" },
  "cancelLeaseExpiresAt": "2026-08-10T00:21:40.882111085+02:00"
}

Note what that did. Taking the lease stops the machine immediately — the mode goes to emergencyStop — and starts a countdown, visible to every connected client as cancelLeaseExpiresAt. It is the interface's "are you sure" made explicit in the protocol, so that a second client can see a cancel is being considered.

Then either commit it:

curl --insecure -b cookies.txt -X PUT https://kilobaser.lab.example.org/api/control/cancel/confirm

or release it and let the run continue:

curl --insecure -b cookies.txt -X PUT https://kilobaser.lab.example.org/api/control/cancel/abort

Do not take the lease speculatively. Between taking it and deciding, the Kilobaser is stopped.

After a confirmed cancel the Kilobaser runs a recovery protocol to get itself back to a safe state — lid closed, cartridge in a known position. It can take up to ten minutes, it has checkpoints of its own, and they have to be answered like any other run. A canceled synthesis is not finished when confirm returns; it is finished when the machine is idle again. See General cancel in Operation.

Canceling is not always expensive. If it happens within 30 seconds of the lid closing, the chip and the vial can both still be reused; after that the linker molecules have been consumed and the chip cannot. Either way the cartridge stays installed — it is only discarded when it is swapped. See Consumables in the Kilobaser manual.

1.2 Errors block everything else

If any error is active, cancel refuses:

{"error": "{\"code\": \"1-1-17\", \"message\": \"Could not proceed, when errors are active!\"}"}

This surprises people, because an error is often exactly when you want to cancel. The order is: clear the error, then cancel.

Active errors are in GET /api/init under errors, and arrive as an errors event whenever the set changes:

[
  {
    "id": "2026-08-09T22:10:49Z-56cd646c",
    "code": "1-2-24",
    "message": "Unexpected power outtage",
    "active": true,
    "type": "powerOutage"
  }
]

When the last error clears, the event fires with an empty payload — which may be null rather than []. Coerce it, or a client will crash on recovery rather than on failure.

The same error at the Kilobaser, where somebody has to press CONFIRM:

The device showing error code 1-2-24, a power outage, with a confirm button

1.3 Acknowledging an error

PUT /api/errors/handle/:id, with the error object and a decision about the run:

curl --insecure -b cookies.txt \
  -X PUT https://kilobaser.lab.example.org/api/errors/handle/2026-08-09T22:10:49Z-56cd646c \
  -H 'Content-Type: application/json' \
  -d '{"cancelRun": true, "error": {"id": "2026-08-09T22:10:49Z-56cd646c", "code": "1-2-24"}}'

cancelRun decides what happens to whatever was running: true abandons it, false acknowledges the error and leaves the run in place to be continued or canceled separately.

The response echoes the error back with active still true. That is the object you submitted, not the new state. To confirm it actually cleared, look at the errors event or re-read /api/init — do not trust the echo.

1.4 Errors are not exceptions

An error here means the Kilobaser has a physical problem — a lid that did not reach its endstop, pressure out of range, a cartridge removed while in use. It is not the mechanism for reporting a bad request; those come back as HTTP errors on the call that caused them.

So an active error usually needs a person, and a client that clears errors automatically so it can keep going is defeating the purpose. kb_run_head.py takes the opposite line:

! error 1-2-24: Unexpected power outtage
refusing to answer while an error is active -- clear it first

Report it to whoever is responsible and stop. The exception is an error you understand specifically and can act on — then handle that code, and only that code.

1.5 When the device restarts

Worth knowing because it is the one you will hit while developing. If the Kilobaser reboots or is updated mid-run:

  • every session ends, because sessions are held in memory. Your next call fails with 2-1-4, at HTTP 400. Log in again.
  • your event stream stops. Reconnect and re-prime from /api/init; nothing is replayed.
  • an error is waiting, 1-2-24 Unexpected power outtage, and it will block cancel until acknowledged.
  • the interrupted run is still there, in whatever state it reached.

A client that handles this case handles most of the others for free, which is why it is worth deliberately restarting a test machine once and watching what your code does.

1.6 Errors worth retrying

Situation Retry
2-1-4 session cookie missing yes, after logging in again
network failure or dropped stream yes, with backoff
1-1-8 something already running yes, later
1-1-17 errors are active only after clearing them
1-1-9 not first in queue no, reorder instead
2-11-11, 2-11-12, 2-11-28 bad sequence no, the request is wrong
2-11-20 invalid combination no, the cartridge and chip do not go together
2-1-5 insufficient permissions no, wrong account

See error codes for the full list.