The TypeScript SDK is designed so that a TruLayer ingest outage never becomes an application outage. This page documents the default behavior and the one opt-in knob for teams who deliberately want the opposite tradeoff.Documentation Index
Fetch the complete documentation index at: https://docs.trulayer.ai/llms.txt
Use this file to discover all available pages before exploring further.
Default — drop and warn
When the ingest API is unreachable (network error) or returns a transient status (5xx), the SDK:
- Retries the batch up to 3× with exponential backoff (500 ms, 1 s, 2 s).
- On the third failure, drops the batch in-memory and emits a single
console.warn. - Suppresses warnings for subsequent failures within a 60-second window to avoid log flooding — a fresh warning is emitted once the window rolls over.
Opt-in — TRULAYER_FAIL_MODE=block
Set TRULAYER_FAIL_MODE=block to make client.shutdown() (and the flush that runs during shutdown) raise a typed TruLayerFlushError when a batch exhausts its retries.
TruLayerFlushError exposes two fields:
batchSize: number— number of traces in the failed batch.cause: unknown— the underlying network or HTTP error.
When to use block mode
Block mode is a niche tool. Reach for it only when:- The workload is a batch job whose entire value depends on TruLayer receiving the output (eval pipelines, backfills, scheduled quality runs).
- Silently losing traces is materially worse than surfacing an error to the operator.
- The caller is prepared to handle
TruLayerFlushError— typically by failing the job and retrying the whole run.
- User-facing request handlers (HTTP routes, gRPC servers). A transient ingest outage will cascade into customer-visible failures.
- Background services that must survive observability outages (payment processors, auth flows, webhooks).
Zero-network — TRULAYER_MODE=local
For CI and offline development, set TRULAYER_MODE=local. The SDK swaps the HTTP sender for an in-memory LocalBatchSender that stores every trace for inspection, never touches the network, and never warns.
@trulayer/sdk/testing helpers for assertions on captured traces.
Replay — TRULAYER_MODE=replay
Set TRULAYER_MODE=replay together with TRULAYER_REPLAY_FILE=<path> to load a previously captured JSONL file on init(). Useful for golden-file regression tests and reproducing a production trace locally.
TRULAYER_MODE=replay implies local — replayed traces never escape to the live API, because they were produced by a previous capture and would double-count in the dashboard. Malformed JSONL lines are skipped with a warning.
Decision guide
| Scenario | Recommended mode |
|---|---|
| Production HTTP service | Default (drop + warn) |
| Background worker with SLO on ingest | Default (drop + warn) |
| Nightly eval / backfill job | TRULAYER_FAIL_MODE=block |
| CI unit tests | TRULAYER_MODE=local |
| CI integration tests against a golden capture | TRULAYER_MODE=replay + TRULAYER_REPLAY_FILE |
| Local development without an API key | TRULAYER_MODE=local |
Archived project
HTTP403 responses with code: "error.project.archived" are treated differently from other errors. They indicate that the project associated with your API key has been archived — a deliberate configuration change, not a transient failure.
When the SDK receives this response:
- It logs an ERROR-level message via
console.error: - The exporter is permanently disabled for that client instance. Subsequent flush attempts are no-ops and produce no further log output.
- Your application continues running normally — only TruLayer observability is suspended.
Why the exporter does not retry
A403 is an authoritative refusal. Retrying would produce noise without any possibility of success. The SDK treats this the same way a browser treats an HTTP 403: stop, log, and do not retry.
Resuming after unarchiving
Unarchiving the project (from Projects settings at app.trulayer.ai/projects) restores ingest immediately — no key rotation needed. However, any already-running client instance that received the 403 will not automatically resume. You must either:- Restart the process — the new process starts a fresh client that will send normally.
- Create a new client — call
new TruLayer(...)again with the same API key. The new client is independent of the disabled one.
Detecting the error programmatically
In block mode (TRULAYER_FAIL_MODE=block), the TruLayerFlushError thrown on permanent 403s carries a statusCode property you can inspect:
See also
- Testing helpers — in-memory assertions against captured traces.
- TypeScript SDK reference — full type signatures for
TruLayerFlushErrorand the error hierarchy. - Project lifecycle — archiving, unarchiving, and the effect on active API keys.