---
title: Observability Utilities
description: Hydrate step I/O, parse display names, and decrypt workflow data using workflow/observability.
type: reference
summary: "Functions: hydrateResourceIO(), parseStepName(), parseWorkflowName(), parseClassName(), getEncryptionKeyForRun(), hydrateResourceIOWithKey()."
prerequisites:
  - /docs/api-reference/workflow-api/get-world
related:
  - /docs/api-reference/workflow-api/world/storage
keywords:
  - workflow/observability
  - hydrateResourceIO
  - observabilityRevivers
  - parseStepName
  - parseWorkflowName
  - parseClassName
  - getEncryptionKeyForRun
  - hydrateResourceIOWithKey
  - data hydration
  - devalue deserialization
  - encryption decryption
  - display name parsing
---

The `workflow/observability` module provides utilities for working with workflow data in observability and debugging tools. It includes functions to hydrate serialized step I/O, parse machine-readable names into display-friendly formats, and decrypt encrypted workflow data.

## Import

```typescript lineNumbers
import { // [!code highlight]
  hydrateResourceIO, // [!code highlight]
  observabilityRevivers, // [!code highlight]
  parseStepName, // [!code highlight]
  parseWorkflowName, // [!code highlight]
  parseClassName, // [!code highlight]
} from "workflow/observability"; // [!code highlight]
```

## Data Hydration

### hydrateResourceIO()

Deserialize step or run data that was serialized using the [devalue](https://github.com/Rich-Harris/devalue) format. Required to display step input/output in your UI.

```typescript lineNumbers
import { hydrateResourceIO, observabilityRevivers } from "workflow/observability"; // [!code highlight]

const step = await world.steps.get(runId, stepId);
const hydrated = hydrateResourceIO(step, observabilityRevivers); // [!code highlight]
console.log(hydrated.input, hydrated.output);
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `resource` | `Step \| WorkflowRun` | The step or run with serialized data |
| `revivers` | `Revivers` | Reviver functions for deserialization. Use `observabilityRevivers` for standard use. |

**Returns:** The resource with hydrated `input` and `output` fields.

### observabilityRevivers

A set of reviver functions that handle standard workflow serialization types (Date, Map, Set, Error, etc.).

## Name Parsing

Workflow and step names are stored as machine-readable identifiers. These utilities extract display-friendly names. All return `{ shortName: string, moduleSpecifier: string } | null`.

### parseStepName()

```typescript lineNumbers
import { parseStepName } from "workflow/observability"; // [!code highlight]

const parsed = parseStepName("step//./src/workflows/order//processPayment"); // [!code highlight]
// parsed?.shortName → "processPayment"
// parsed?.moduleSpecifier → "./src/workflows/order"
```

### parseWorkflowName()

```typescript lineNumbers
import { parseWorkflowName } from "workflow/observability"; // [!code highlight]

const parsed = parseWorkflowName("workflow//./src/workflows/order//processOrder"); // [!code highlight]
// parsed?.shortName → "processOrder"
```

### parseClassName()

```typescript lineNumbers
import { parseClassName } from "workflow/observability"; // [!code highlight]

const parsed = parseClassName("class//./src/models//User"); // [!code highlight]
// parsed?.shortName → "User"
```

## Encryption

For workflows with encrypted step data, decrypt before hydrating.

### getEncryptionKeyForRun()

Retrieve the encryption key used for a specific workflow run.

{/* @expect-error:2305 */}
```typescript lineNumbers
import { getEncryptionKeyForRun } from "workflow/observability"; // [!code highlight]

const key = await getEncryptionKeyForRun(runId); // [!code highlight]
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `runId` | `string` | The workflow run ID |

**Returns:** Encryption key for the run

### hydrateResourceIOWithKey()

Hydrate step or run data using a decryption key. Use this instead of `hydrateResourceIO()` when data is encrypted.

{/* @expect-error:2305,2724 */}
```typescript lineNumbers
import { getEncryptionKeyForRun, hydrateResourceIOWithKey } from "workflow/observability"; // [!code highlight]

const key = await getEncryptionKeyForRun(runId); // [!code highlight]
const hydrated = hydrateResourceIOWithKey(step, key); // [!code highlight]
```

**Parameters:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `resource` | `Step \| WorkflowRun` | The step or run with encrypted serialized data |
| `key` | `EncryptionKey` | The encryption key from `getEncryptionKeyForRun()` |

**Returns:** The resource with decrypted and hydrated `input` and `output` fields.

## Examples

### Parse Display Names for a Run's Steps

```typescript lineNumbers
import { getWorld } from "workflow/runtime";
import { parseStepName, parseWorkflowName } from "workflow/observability"; // [!code highlight]

const world = await getWorld();
const run = await world.runs.get(runId, { resolveData: "none" });
console.log("Workflow:", parseWorkflowName(run.workflowName)?.shortName); // [!code highlight]

const steps = await world.steps.list({ runId, resolveData: "none" });
for (const step of steps.data) {
  const parsed = parseStepName(step.stepName); // [!code highlight]
  console.log(`  ${parsed?.shortName}: ${step.status}`); // [!code highlight]
}
```

## Related

- [Storage](/docs/api-reference/workflow-api/world/storage) — Query runs, steps, hooks, and events
- [Serialization](/docs/foundations/serialization) — How workflow data is serialized
