Skip to content

Fallback on critical failures

A fallback Task runs as a backup when a critical Task fails or is skipped. Its enabled reads any value that signals that — typically the critical Task’s .status, but a .result or a tag works just as well.

In the example, dashboard is the critical Task — it reads auth.result. If auth fails, dashboard is skipped. If dashboard itself fails, the result is the same: dashboard.status is not "done", so fallback runs. Reading .status instead of .result is what keeps fallback enabled — status is always available, even after a skip.

Uncomment the throw to see it:

import { compose, createTask } from "@app-compose/core"
const auth = createTask({
name: "auth",
run: {
fn: () => {
// uncomment to make auth fail
// console shows "fallback shown" instead of "dashboard ready"
// 👇
// throw new Error("[auth]: failed")
return { id: 1 }
},
},
})
// critical to the app
const dashboard = createTask({
name: "dashboard",
run: {
context: auth.result,
fn: (user) => console.log(`#${user.id} dashboard is ready`),
},
})
// runs when dashboard doesn't reach "done"
const fallback = createTask({
name: "fallback",
run: { fn: () => console.log("fallback shown") },
enabled: {
context: dashboard.status,
fn: (status) => status !== "done",
},
})
compose()
.step(auth)
.step(dashboard)
.step(fallback)
.run()

For shorter enabled blocks, when from @app-compose/coda returns the { context, fn: Boolean } pair in a single call.