---
title: "Model stylesheet templates and failure routing"
date: "2026-08-25"
---

Workflows can now set graph-level `on_failure="exit"` to stop after a failed
node when no explicit recovery route matches. Fabro skips the unconditional
edge, checks configured retry targets, and ends the run as failed if no retry
target exists.

The default `on_failure="route"` preserves existing workflow behavior.

A node can also set its own `on_failure` to override the graph policy in
either direction: a best-effort node can use `on_failure="route"` inside an
`exit` graph, or a single critical node can use `on_failure="exit"` while the
rest of the graph keeps the default.

```dot
digraph Build {
    graph [on_failure="exit"]
    start [shape=Mdiamond]
    exit [shape=Msquare]
    plan [prompt="Plan the work"]
    implement [prompt="Implement the plan"]
    verify [prompt="Verify the implementation"]

    start -> plan -> implement -> verify -> exit
}
```

## Model stylesheet templates

The root graph's `model_stylesheet` now supports MiniJinja templates. A stylesheet can use typed run inputs and server-managed variables through `inputs` and `vars`. Conditions, loops, filters, macros, local values, and static includes use the same template engine as workflow goals and prompts.

Fabro renders the stylesheet before parsing and applying its rules. Undefined values produce the existing `template_undefined_variable` diagnostic. Offline validation skips stylesheet syntax checks until those values are available, which avoids a second error from incomplete generated stylesheet text.

Stylesheet templates do not expose `goal`, `env`, or `secrets`. Stylesheets on imported graphs remain ignored and now produce an `imported_model_stylesheet_ignored` warning.
