fix: Report an incomplete DynamoDB auto-config cache write - #874
Merged
Merged
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ 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 6b2f796. Configure here.
SetAll returned nil even when it had written nothing. A failed batch, an unprocessed item, or an environment over the size limit was logged and skipped, and the function reported success anyway. The damage is not at write time. A later startup reads that partial snapshot and serves it as the whole configuration, marking Relay fully configured with a subset of its environments. SDKs for the missing ones then get a 401 rather than a 503, and a LaunchDarkly SDK treats a 401 on its data source as terminal, so it stops retrying for good. Count everything that could not be written and return an error naming the loss. The write still continues past a failed batch, because a partial cache is worth more than none, but the caller is told instead of reassured; persistPut already logs that error, so the problem surfaces when it happens. Redis is unaffected: its SetAll is atomic. Reading a partial snapshot is still indistinguishable from reading a complete one. That needs a completeness marker in the cache, which is a schema change and its own piece of work.
keelerm84
force-pushed
the
mk/SDK-3102/dynamodb-incomplete-write
branch
from
September 16, 2026 14:43
6b2f796 to
d58ff62
Compare
kinyoklion
approved these changes
Sep 16, 2026
keelerm84
pushed a commit
that referenced
this pull request
Sep 17, 2026
🤖 I have created a release *beep* *boop* --- ## [8.22.0](v8.21.0...v8.22.0) (2026-09-16) ### Features * Adopt go-server-sdk v7.17.0 so an upstream 401 retries ([#856](#856)) ([e152af7](e152af7)) * Back off big segment synchronization on a rejected SDK key ([#857](#857)) ([6ede85b](6ede85b)) * Classify transport failures as normal, including certificate failures ([#873](#873)) ([c3b6850](c3b6850)) * Keep retrying a rejected auto-configuration key ([#866](#866)) ([4bf3bb9](4bf3bb9)) * Report the auto-configuration stream's health in the status resource ([#870](#870)) ([5c1e3ee](5c1e3ee)) ### Bug Fixes * **autoconfig:** refresh stored environment defaults on update (SEC-9484) ([#842](#842)) ([e04e3e2](e04e3e2)) * **deps:** bump golang.org/x/crypto to v0.55.0 for CVE-2026-56854 ([#848](#848)) ([360d624](360d624)) * **deps:** bump golang.org/x/crypto to v0.56.0 for CVE-2026-78662 and CVE-2026-56855 ([#854](#854)) ([6d5d346](6d5d346)) * **deps:** bump supported Go versions to 1.27.0 and 1.26.7 ([#837](#837)) ([9b4fb46](9b4fb46)) * **deps:** bump supported Go versions to 1.27.1 and 1.26.8 ([#852](#852)) ([4b06ed6](4b06ed6)) * emit Vary: Origin on CORS responses (SEC-9501) ([#844](#844)) ([78a8f05](78a8f05)) * Report an incomplete DynamoDB auto-config cache write ([#874](#874)) ([0964dc0](0964dc0)) * **security:** redact all credential-bearing URL components in status dbServer ([#846](#846)) ([20effc5](20effc5)) * **streams:** treat a nil replay result as no event instead of panicking ([#845](#845)) ([7d7eace](7d7eace)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
dynamoDBStore.SetAllreturnednileven when it had written nothing. A failed batch, an unprocessed item, or an environment over the size limit was logged and skipped, and the function reported success anyway.The damage is not at write time. A later startup reads that partial snapshot and serves it as the whole configuration, marking Relay fully configured with a subset of its environments. SDKs for the missing ones then get a
401rather than a503— and a LaunchDarkly SDK treats a401on its data source as terminal, so it stops retrying for good rather than backing off and recovering.The fix counts everything that could not be written — build failures, size-limit drops, failed batches, unprocessed items — and returns an error naming the loss. The write still continues past a failed batch, because a partial cache is worth more than none, but the caller is told instead of reassured.
persistPutalready logsSetAll's error, so the problem surfaces when it happens rather than on some later startup.Redis is unaffected: its
SetAllis atomic via MULTI/EXEC.Not fixed here
Reading a partial snapshot is still indistinguishable from reading a complete one, so a snapshot written before this change is still served as authoritative. Detecting that needs a completeness marker in the cache, which is a schema change and its own piece of work.
Origin
Found by a review of #866 and split out of it. It has nothing to do with retry behavior beyond having been noticed at the same time.
Note
Overview
dynamoDBStore.SetAllnow fails when the DynamoDB snapshot is incomplete instead of always returning success after partial writes.The store tracks every item that cannot be written—marshal/build errors, oversize drops, whole failed
BatchWriteItemchunks, and unprocessed items—and returns an error like "N of M items could not be written". Batch writes still continue after a failed chunk so a partial cache can land, but callers are no longer told the write fully succeeded.batchWriteis changed to return a drop count to support this accounting without double-counting items in the error total.New
dynamodb_store_test.goexercises this with an httptest fake DynamoDB: success path, unprocessed items, failed batches, oversized envs (partial write still happens), and 25-item chunking.Reviewed by Cursor Bugbot for commit 1a1002c. Bugbot is set up for automated code reviews on this repo. Configure here.