Skip to content

feat: add X-LaunchDarkly-Instance-Id header to server-node SDK (SDK-2358)#1377

Open
keelerm84 wants to merge 2 commits into
mainfrom
mk/sdk-2358-instance-id
Open

feat: add X-LaunchDarkly-Instance-Id header to server-node SDK (SDK-2358)#1377
keelerm84 wants to merge 2 commits into
mainfrom
mk/sdk-2358-instance-id

Conversation

@keelerm84
Copy link
Copy Markdown
Member

@keelerm84 keelerm84 commented May 12, 2026

Summary

Adds the X-LaunchDarkly-Instance-Id header to every outbound polling, streaming, and event request from @launchdarkly/node-server-sdk. Value is a v4 UUID generated once per LDClientImpl via platform.crypto.randomUUID() and shared with the requestor, streaming processor, and event processor through baseHeaders.

The instanceId parameter on the shared defaultHeaders helper is opt-in so the client SDK and edge SDKs in this monorepo (akamai-base, cloudflare, fastly, vercel, shopify-oxygen, server-ai) are unaffected — they go through different code paths and continue to omit the header.

Test plan

  • `@launchdarkly/js-sdk-common` — 473 / 473 passing (17 http tests incl. 3 new)
  • `@launchdarkly/js-server-sdk-common` — 990 / 990 passing (3 new instance-id tests)
  • `@launchdarkly/node-server-sdk` — 63 / 63 passing
  • Lint clean across all 3 affected workspaces
  • Edge SDKs (cloudflare, vercel, akamai-base) still build
  • CI green

Note

Medium Risk
Modifies shared request header construction and server SDK initialization to propagate a new per-instance UUID header on all outbound requests, which could affect integrations that depend on exact headers or request caching behavior.

Overview
Adds opt-in support for the X-LaunchDarkly-Instance-Id header by extending shared defaultHeaders to accept an instanceId and include it only when provided.

Updates the shared server implementation (LDClientImpl) to thread internalOptions.instanceId into its base headers for both FDv1 and FDv2 paths, and updates the Node server SDK (LDClientNode) to generate a per-client v4 UUID via platform.crypto.randomUUID() and pass it through internalOptions.

Expands coverage with new unit tests validating header presence/absence and UUID behavior, and advertises the new instance-id capability in the Node contract test service.

Reviewed by Cursor Bugbot for commit 8fa11d7. Bugbot is set up for automated code reviews on this repo. Configure here.

…K-2358)

Per SCMP-server-connection-minutes-polling section 1.1, server SDKs must
send a per-instance v4 GUID on every polling request to enable Server
Connection Minutes estimation. The GUID is generated once per SDK
instance and stable for that instance's lifetime.

We attach the GUID to the shared base headers in LDClientImpl
(constructFDv1 and constructFDv2), so it rides on every outbound
request -- polling, streaming, and events -- matching the cross-SDK
contract tests. The shared defaultHeaders helper now accepts an optional
instanceId parameter so client / edge SDKs are not affected.

Section 1.3 (polling-interval header) is out of scope for this ticket.

Changes:
- packages/shared/common/src/utils/http.ts: extend LDHeaders and
  defaultHeaders to support an optional instanceId
- packages/shared/sdk-server/src/LDClientImpl.ts: generate one UUID per
  client (via platform.crypto.randomUUID) and pass it to defaultHeaders
- packages/sdk/server-node/contract-tests: register "instance-id"
  capability
- Unit tests for both layers; updated bigSegments test mock crypto
@keelerm84 keelerm84 requested a review from a team as a code owner May 12, 2026 20:59
@github-actions
Copy link
Copy Markdown
Contributor

@launchdarkly/js-sdk-common size report
This is the brotli compressed size of the ESM build.
Compressed size: 26389 bytes
Compressed size limit: 29000
Uncompressed size: 129320 bytes

@github-actions
Copy link
Copy Markdown
Contributor

@launchdarkly/browser size report
This is the brotli compressed size of the ESM build.
Compressed size: 179469 bytes
Compressed size limit: 200000
Uncompressed size: 830878 bytes

@github-actions
Copy link
Copy Markdown
Contributor

@launchdarkly/js-client-sdk-common size report
This is the brotli compressed size of the ESM build.
Compressed size: 38487 bytes
Compressed size limit: 39000
Uncompressed size: 211236 bytes

@github-actions
Copy link
Copy Markdown
Contributor

@launchdarkly/js-client-sdk size report
This is the brotli compressed size of the ESM build.
Compressed size: 31884 bytes
Compressed size limit: 34000
Uncompressed size: 113699 bytes

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default mode and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 3996e7e. Configure here.

Comment thread packages/shared/sdk-server/src/LDClientImpl.ts
The previous commit (3996e7e) called platform.crypto.randomUUID() from
LDClientImpl.constructFDv1/constructFDv2, but LDClientImpl is also the
base class for the Akamai, Cloudflare, Fastly, Vercel, and Shopify
Oxygen edge SDKs. Those edge platforms either don't provide a working
randomUUID() in their test mocks (Akamai) or shouldn't be advertising
instance-id at all.

This commit moves UUID generation to LDClientNode, which uses the Node
platform's always-available crypto.randomUUID, and threads the
generated value through ServerInternalOptions.instanceId. LDClientImpl
attaches the header only when instanceId is supplied, leaving edge SDKs
unaffected.

Also reverts the workaround in the big-segments test crypto mock — no
longer needed now that LDClientImpl doesn't call randomUUID on its own.

Tests:
- @launchdarkly/js-server-sdk-common: 989 passing (5 skipped)
- @launchdarkly/node-server-sdk: 65 passing (+2 new instance-id tests)
- @launchdarkly/akamai-server-base-sdk: 6 passing (previously 6 failing)
- Lint clean
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant