Obelisk 0.25.4 and handling of WASM traps

2025-10-06

Obelisk is an open-source deterministic workflow engine that runs, stores, and replays WASM-based workflows using SQLite.

The headline change in v0.25: every function in workflows and activities is now required to be fallible. Obelisk maps execution-failed errors into the called function's return type. This ensures traps and errors are handled explicitly instead of silently breaking execution.

Breaking API Changes

Each function invoked by Obelisk, whether a workflow or an activity, must be fallible. More precisely, it means that the return type must be one of following:

Previously, functions were free to return any WIT-supported value. However, this flexibility caused issues:

This was previously mitigated with the execution-failed error. The parent execution had to choose between:

In the latter case, the parent execution itself would abort with an "Unhandled child execution error".

This design added complexity for both workflow authors and the runtime. Workflow authors had to decide whether a child’s execution error was fatal or if cleanup or compensation should follow.

Mistakingly calling a child function directly could mean resources were never freed, making workflows brittle.

The runtime faced similar complexity, especially around join set closing. It was unclear whether an execution-failed during a Join Set Close should be treated as fatal for the parent workflow or simply ignored as other unawaited execution results.

With the new design, the runtime maps execution-failed to one of the supported error types. It builds on the strength of the WASM isolation - effectively making each invocation live in its own "blast zone", so that even unusual errors like running out of memory will not affect the caller.

When handling such errors, not every activity failure needs to derail the workflow. For example, if an email-sending activity fails with execution-failed, the email may not be sent, but the workflow can still continue without issue.

If an activity is crucial, the workflow must exit. Making the error handling explicit has one big advantage especially for sagas: Since it is now impossible to overlook this kind of error, the workflow must now choose whether to abort all further actions or whether a compensating logic should be applied. This could include shutting down VMs or other resources that must not be left in an unknown state.

In conclusion, the new requirement for fallible functions simplifies both workflow authoring and runtime behavior. By mapping execution-failed errors into the called function's return type, workflows become safer, more predictable, and easier to reason about, allowing developers to handle failures explicitly and reliably without risking hidden resource leaks or unexpected early returns.

Ergonomics changes

Other changes are mostly focused on CLI:

« Back to Blog List