# OmniRoute Error Sanitization and Message Handling Pattern Explained

> Learn the OmniRoute error sanitization and message handling pattern. This pattern centralizes error management, preventing sensitive data leaks to clients.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: deep-dive
- Published: 2026-08-07

---

**OmniRoute implements a centralized error-handling pipeline that prevents stack traces, file paths, and credentials from ever reaching clients by funneling all errors through a single sanitization layer.**

The OmniRoute project, maintained at `diegosouzapw/OmniRoute`, enforces strict security guarantees for error responses across its entire API surface. Every handler, SSE stream writer, and combo-diagnostics module delegates error construction to a dedicated utilities layer. This article examines the implementation in [`open-sse/utils/error.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/error.ts) and demonstrates how the pattern achieves defense-in-depth for production deployments.

## Core Sanitization Functions

Three primary functions form the foundation of OmniRoute's error sanitization. Each operates at a different level of abstraction, from simple string cleaning to full payload reconstruction.

### sanitizeErrorMessage

The `sanitizeErrorMessage(message)` function applies the first line of defense. Located at [`open-sse/utils/error.ts#L63-L74`](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/utils/error.ts#L63-L74), it performs these operations in sequence:

- Truncates messages exceeding length limits
- Tokenizes the first line to drop stack trace continuations
- Replaces absolute POSIX and Windows paths with the literal `<path>`
- Redacts data URLs, authentication headers, and key-like tokens

This function is **universally applied** to every user-facing error string before transmission.

### sanitizeUpstreamDetails

Upstream providers may return arbitrary JSON payloads containing sensitive metadata. The `sanitizeUpstreamDetails(value, depth = 0)` function at [`open-sse/utils/error.ts#L88-L104`](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/utils/error.ts#L88-L104) recursively sanitizes these responses with configurable guards:

- **Depth limitation**: Hard stops at `MAX_DEPTH = 4`
- **Key blocking**: Drops properties matching the `BLOCKED_KEYS` credential regex
- **String sanitization**: Runs all string values through `sanitizeErrorMessage`
- **Array capping**: Limits arrays to 32 elements

### buildErrorBody

The `buildErrorBody(statusCode, message, upstreamDetails?, classification?)` function at [`open-sse/utils/error.ts#L121-L146`](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/utils/error.ts#L121-L146) constructs the final response structure. It:

1. Looks up default `type` and `code` values from HTTP status via `getErrorInfo`
2. Sanitizes the supplied message
3. Optionally attaches cleaned upstream details under `upstream_details`
4. Returns an **OpenAI-compatible schema**: `{ error: { message, type?, code? }, upstream_details? }`

## High-Level Error Response Helpers

Four exported helpers abstract the core functions for different response contexts.

| Helper | Purpose | Source Location |
|--------|---------|-----------------|
| `errorResponse(statusCode, message)` | JSON responses from non-streaming handlers | [`open-sse/utils/error.ts#L443-L50`](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/utils/error.ts#L443-L50) |
| `writeStreamError(writer, statusCode, message)` | SSE stream error events | [`open-sse/utils/error.ts#L58-L66`](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/utils/error.ts#L58-L66) |
| `errorResponseWithComboDiagnostics(status, msg, diagnostics, opts)` | Combo routing failures with sanitized diagnostic headers | [`open-sse/utils/error.ts#L86-L131`](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/utils/error.ts#L86-L131) |
| `createErrorResult(...)` | Internal pipeline representation carrying raw message for classification while exposing sanitized response | [`open-sse/utils/error.ts#L527-L588`](https://github.com/diegosouzapw/OmniRoute/blob/release/v3.8.50/open-sse/utils/error.ts#L527-L588) |

The `errorResponseWithComboDiagnostics` helper deserves special attention. When combo routing terminates, it builds a response that simultaneously:

- Contains the standard sanitized error body
- Embeds a **sanitized diagnostic trace** in custom `x-omniroute-*` headers
- Adds the same trace under `diagnostics` in the JSON payload
- Optionally includes recovery hints via `x-omniroute-recovery-*` headers

## Error Handling in the Request Pipeline

All HTTP API entry points eventually delegate to these helpers. The following excerpts from handler files demonstrate consistent application.

### Chat Handler Validation

```ts
// src/sse/handlers/chat.ts
import { errorResponse } from "@omniroute/open-sse/utils/error.ts";

if (!model) return errorResponse(HTTP_STATUS.BAD_REQUEST, "Missing model");

```

Line 454 of this file shows validation failures funneled through the sanitization layer.

### Reasoning Routing Handler

```ts
// src/sse/handlers/reasoningRouting.ts
return errorResponse(HTTP_STATUS.SERVICE_UNAVAILABLE, msg);

```

Upstream failures receive identical treatment.

### SSE Streaming Errors

```ts
// src/sse/handlers/chatHelpers.ts
await writeStreamError(writer, HTTP_STATUS.UNAUTHORIZED, message);

```

Streaming contexts use `writeStreamError` to emit clean JSON payloads directly into the SSE stream.

These patterns repeat across `src/sse/handlers/*.ts`. Search for `errorResponse(` imports to locate all usage sites.

## Specialized Error Types

OmniRoute provides domain-specific helpers for operational scenarios.

### Provider Circuit-Breaker

The `providerCircuitOpenResponse` function returns HTTP 503 with:

- `Retry-After` header for client backoff
- Machine-readable `code: "provider_circuit_open"`

### Model Cooldown

The `modelCooldownResponse` function returns HTTP 429 with:

- Structured `model_cooldown` body
- `Retry-After` header indicating cooldown expiration

Both helpers internally invoke `sanitizeErrorMessage`, maintaining the same security guarantees.

## Implementation Examples

### Basic API Route Error

```ts
import { errorResponse } from "@omniroute/open-sse/utils/error.ts";

export async function POST(req: Request) {
  const body = await req.json();
  if (!body.prompt) {
    return errorResponse(400, "Missing required field: prompt");
  }
  // Normal processing continues...
}

```

The raw message "Missing required field: prompt" passes through `sanitizeErrorMessage` before reaching the client.

### Streaming Context Error

```ts
import { writeStreamError } from "@omniroute/open-sse/utils/error.ts";

async function streamResponse(writer: WritableStreamDefaultWriter<Uint8Array>) {
  try {
    const data = await fetchRemote();
    // ...stream data...
  } catch (e) {
    await writeStreamError(writer, 502, e);
  }
}

```

The raw exception `e` is never serialized directly—only its sanitized representation appears in the stream.

### Combo Routing with Diagnostics

```ts
import { errorResponseWithComboDiagnostics } from "@omniroute/open-sse/utils/error.ts";

const diagnostics = {
  poolSize: 12,
  attempted: 5,
  excluded: [{ provider: "openai", model: "gpt-4o-mini", reason: "rate_limit" }],
  attemptOrder: [{ provider: "anthropic", model: "claude-3" }],
  terminalReason: "all_candidates_exhausted",
  recovery: { action: "try-auto", next_step: "Switch to auto-combo mode" },
};

return errorResponseWithComboDiagnostics(503, "Combo exhausted", diagnostics);

```

Diagnostic objects are recursively sanitized before appearing in headers or JSON payloads.

## Key Files Reference

| File | Role |
|------|------|
| [`open-sse/utils/error.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/error.ts) | Central sanitization and response factory—the core of the pattern |
| [`src/shared/utils/apiResponse.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/shared/utils/apiResponse.ts) | Higher-level management route responses (delegates to streaming utils for sanitization) |
| [`src/sse/handlers/chat.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/sse/handlers/chat.ts) | Handler demonstrating `errorResponse` usage |
| [`src/sse/handlers/chatHelpers.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/sse/handlers/chatHelpers.ts) | SSE streaming with `writeStreamError` |
| [`src/sse/handlers/reasoningRouting.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/sse/handlers/reasoningRouting.ts) | Upstream failure handling |
| [`tests/unit/combo/recovery-hint.test.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/tests/unit/combo/recovery-hint.test.ts) | End-to-end validation of header sanitization |

## Summary

- **Single source of truth**: All errors route through [`open-sse/utils/error.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/open-sse/utils/error.ts)
- **Layered sanitization**: String cleaning → recursive payload cleaning → structured response assembly
- **No leakage guarantee**: Stack traces, paths, credentials, and upstream internals never reach clients
- **OpenAI compatibility**: Standardized error schema eases client integration
- **Operational visibility**: Diagnostic headers and recovery hints maintain debugging utility without compromising security

## Frequently Asked Questions

### How does OmniRoute prevent credential leakage in error messages?

OmniRoute applies `sanitizeErrorMessage` to every user-facing string. This function redacts data URLs, authentication headers, and key-like tokens using pattern matching. Additionally, `sanitizeUpstreamDetails` drops any JSON property matching the `BLOCKED_KEYS` regex before serialization.

### What is the maximum recursion depth for upstream error sanitization?

The `sanitizeUpstreamDetails` function enforces `MAX_DEPTH = 4` to prevent performance degradation on deeply nested upstream responses. Arrays are additionally capped at 32 elements, and all strings undergo the standard sanitization pass.

### Can I include debugging information in production error responses?

Yes—use `errorResponseWithComboDiagnostics` to attach sanitized diagnostic traces. These appear in both custom `x-omniroute-*` headers and the JSON payload under `diagnostics`. The same sanitization rules apply, ensuring no sensitive data escapes.

### Does OmniRoute support custom error classifications?

The `buildErrorBody` function accepts an optional `classification` parameter that feeds into the error type/code lookup. Specialized helpers like `providerCircuitOpenResponse` and `modelCooldownResponse` demonstrate predefined classifications for operational scenarios.