> ## Documentation Index
> Fetch the complete documentation index at: https://braintrust.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Span components v4 encoding error on self-hosted after upgrading the SDK

> Resolve "SpanComponents string is not properly encoded" errors on self-hosted deployments caused by upgrading the SDK before the Braintrust data plane.

export const plans_0 = "Any"

export const deployments_0 = "Self-hosted"

export const data_plane_version_0 = undefined

export const use_case_0 = "Use case - A self-hosted deployment starts rejecting spans with a SpanComponents encoding version error after the SDK is upgraded ahead of the Braintrust data plane."

<Note>
  **Applies to:**

  * Plan - {plans_0}
  * Deployment - {deployments_0}
  * {data_plane_version_0}
  * {use_case_0}
</Note>

## Summary

**Issue:** After upgrading the Braintrust SDK, a self-hosted deployment surfaces this error:

```text theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
SpanComponents string is not properly encoded. This library only supports encoding versions up to 3.
```

If you see this message anywhere on a self-hosted instance after upgrading the SDK, this version mismatch is almost certainly the root cause. The most commonly reported symptom is **remote scorer** invocations failing (remote scorers decode the parent span reference the SDK sends), but the same mismatch can show up on other paths that decode span references.

**Cause:** Newer SDK versions generate OpenTelemetry-compatible hex IDs and encode span components using the **v4** format by default. This is the default in both SDKs:

* **Python SDK**: v4 (OTel-compatible) export by default as of **v0.26.0**.
* **TypeScript SDK**: v4 export by default as of **braintrust\@3.21.0**.

An older self-hosted data plane only knows how to decode span components up to **v3**, so any path that decodes a v4-encoded span reference from the SDK rejects it. This happens when the SDK is upgraded *before* the Braintrust deployment is upgraded.

**Resolution:** Either upgrade the Braintrust data plane to a version that understands v4 span components, or pin the SDK back to the legacy (v3) encoding by setting `BRAINTRUST_LEGACY_IDS=true` until you can upgrade.

## Background

By default, recent SDKs generate OpenTelemetry-compatible hex trace/span IDs (16-byte trace id / 8-byte span id) and export span components in the v4 format. Setting `BRAINTRUST_LEGACY_IDS` opts back into the legacy UUID-based IDs with v3 span-component export, which older data planes accept.

The version support is forward-compatible on the SDK side but not on the server side: a decoder can only read encodings up to the version it was built with. Keeping the SDK at or below the data plane's supported version — or upgrading the data plane first — avoids the mismatch.

## Resolution steps

### Option 1: Upgrade Braintrust (recommended)

Upgrade your self-hosted data plane to a version that supports v4 span components. This is the durable fix and lets you keep the newer SDK and OpenTelemetry-compatible IDs.

After upgrading, you can confirm the deployment version from the API URL configuration page:

```text theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
https://www.braintrust.dev/app/[ORGNAME]/p/[PROJECTNAME]/configuration/org/api-url
```

As a general rule, upgrade the Braintrust deployment before (or at the same time as) upgrading SDKs in your applications.

### Option 2: Set `BRAINTRUST_LEGACY_IDS=true` in the SDK

If you cannot upgrade the deployment immediately, force the SDK back to legacy UUID IDs with v3 span-component export by setting the environment variable wherever your instrumented application runs:

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
BRAINTRUST_LEGACY_IDS=true
```

This makes the newer SDK emit span components that an older (v3) data plane can decode.

Leaving `BRAINTRUST_LEGACY_IDS=true` in place is safe even after you later upgrade the data plane — newer data planes still decode v3 span components, so it keeps working. That said, once the data plane is upgraded it's best to remove the flag so you switch back to OpenTelemetry-compatible hex IDs and v4 export.

<Note>
  `BRAINTRUST_LEGACY_IDS` is ignored when `BRAINTRUST_OTEL_COMPAT` is set, because OpenTelemetry compatibility mode requires hex IDs. If you rely on OTel compatibility, upgrade the data plane (Option 1) rather than pinning to legacy IDs.
</Note>
