# Probe Expression Engine Context Variables: Complete Reference for Workflow Automation

> Explore Probe's expression engine context variables. Understand vars, res, req, rt, report, outputs, status, and repeat_index for efficient workflow automation.

- Repository: [Tomohisa Oda/probe](https://github.com/linyows/probe)
- Tags: api-reference
- Published: 2026-03-06

---

**Probe exposes nine context variables in `StepContext` (`vars`, `res`, `req`, `rt`, `report`, `outputs`, `status`, `repeat_index`) and two in `JobContext` (`vars`, `outputs`), all tagged with `expr` struct tags in the source code.**

Probe is an open-source workflow automation tool that evaluates dynamic expressions against runtime data. The expression engine parses both raw expressions and `{{ … }}` templates using variables scoped to either individual steps or entire jobs, as defined in the `linyows/probe` repository.

## Available Context Variables in Probe

The context system relies on Go struct tags to expose fields to the expression evaluator. In [`context.go`](https://github.com/linyows/probe/blob/main/context.go), the `expr:"…"` tags on lines 38‑45 define `StepContext`, while lines 50 and 68 define `JobContext`.

### StepContext Variables

When evaluating expressions inside a step, Probe populates `StepContext` with the following variables:

- **`vars`** — User‑defined variables scoped to the step (`map[string]any`). Access via `step.vars`.
- **`res`** — Result map returned by the action (`map[string]any`). Contains action-specific return data.
- **`req`** — Request data passed to the action (`map[string]any`).
- **`rt`** — Response time information (`ResponseTime` struct). Exposes `rt.duration` (string) and `rt.sec` (float64).
- **`report`** — Human‑readable status report for the step (string).
- **`outputs`** — Step outputs defined in the workflow (`map[string]any`).
- **`status`** — Normalised exit status as integer (`0` = success, `1` = failure).
- **`repeat_index`** — Index of the current iteration when a step is repeated (int). Starts at 0.

### JobContext Variables

For job‑wide expressions, Probe uses `JobContext` with these fields:

- **`vars`** — Job‑wide variables accessible across all steps (`map[string]any`). Access via `job.vars`.
- **`outputs`** — Shared outputs across all jobs (`*Outputs`).

## How to Access Context Variables in Expressions

Probe supports two evaluation modes in [`expr.go`](https://github.com/linyows/probe/blob/main/expr.go): raw boolean expressions for conditional logic and template rendering for string interpolation.

### Raw Expression Evaluation

Use `Eval()` for boolean checks and calculations. The method signature accepts an expression string and a context struct:

```go
expr := &probe.Expr{}
stepCtx := probe.StepContext{
    Vars: map[string]any{
        "threshold": 0.5,
    },
    RT: probe.ResponseTime{
        Duration: "120ms",
        Sec:      0.12,
    },
}

result, err := expr.Eval(`rt.sec < vars.threshold`, stepCtx)
// result == true

```

### Template Syntax

Use `EvalTemplate()` for string interpolation with `{{ … }}` delimiters:

```go
tmpl := "Latency: {{ rt.duration }} ({{ rt.sec }} s) – status {{ status }}"
out, err := expr.EvalTemplate(tmpl, stepCtx)
// out == "Latency: 120ms (0.12 s) – status 0"

```

## Practical Examples for Workflow Logic

The following patterns demonstrate how to leverage context variables in real workflow scenarios, as implemented in [`step.go`](https://github.com/linyows/probe/blob/main/step.go) and [`workflow.go`](https://github.com/linyows/probe/blob/main/workflow.go).

### Evaluating Response Time Thresholds

Compare response time against user‑defined limits using the `rt` variable:

```go
stepCtx := probe.StepContext{
    RT: probe.ResponseTime{Sec: 0.25},
    Vars: map[string]any{"max_latency": 0.5},
}

// Check if response is within acceptable range
valid, _ := expr.Eval(`rt.sec <= vars.max_latency`, stepCtx)
// valid == true

```

### Accessing Job-Level Configuration

Access global configuration set at the job level using `JobContext`:

```go
jobCtx := probe.JobContext{
    Vars: map[string]any{"env": "prod", "region": "us-east-1"},
}

val, _ := expr.Eval(`vars.env == "prod" && vars.region == "us-east-1"`, jobCtx)
// val == true

```

### Handling Step Repetition

When a step repeats, use `repeat_index` to vary behavior per iteration:

```go
stepCtx := probe.StepContext{RepeatIndex: 2}

out, _ := expr.EvalTemplate("Attempt {{ repeat_index }} of 5", stepCtx)
// out == "Attempt 2 of 5"

```

## Summary

- Probe exposes **nine variables** in `StepContext` (`vars`, `res`, `req`, `rt`, `report`, `outputs`, `status`, `repeat_index`) and **two variables** in `JobContext` (`vars`, `outputs`).
- The `expr` struct tags in [`context.go`](https://github.com/linyows/probe/blob/main/context.go) (lines 38‑45 and 50/68) define the mapping between Go fields and expression variable names.
- Use `Eval()` for boolean logic and `EvalTemplate()` for string interpolation with `{{ … }}` syntax.
- `rt.sec` provides float64 response time in seconds, while `rt.duration` provides the formatted string.
- `status` returns `0` for success and `1` for failure, enabling explicit conditional branching.

## Frequently Asked Questions

### How do I check if a step succeeded using context variables?

Evaluate the `status` variable against integer `0`. In [`context.go`](https://github.com/linyows/probe/blob/main/context.go), `StepContext.Status` is defined as `int` with `expr:"status"`, where `0` indicates success and `1` indicates failure. Use the expression `status == 0` in conditionals.

### What is the difference between `step.vars` and `job.vars`?

`step.vars` (the `vars` field in `StepContext`) contains variables scoped to the current step execution, while `job.vars` (the `vars` field in `JobContext`) contains workflow‑wide variables accessible across all steps. Both are `map[string]any` types but exist in different context scopes.

### Can I access the previous step's result in the current step?

Yes, through the `res` variable in `StepContext`. The `Res` field (`map[string]any`) stores the result map returned by the action execution. Reference specific values using dot notation, such as `res.status_code` or `res.body`, depending on what the action returns.

### How does `repeat_index` work in looped steps?

`repeat_index` (exposed from `StepContext.RepeatIndex`) contains the zero‑based index of the current iteration when a step is configured to repeat. It increments automatically with each retry or loop iteration, allowing expressions like `repeat_index < vars.max_retries` to control flow logic.