Skip to content

fix(cdk): follow LastEvaluatedKey when looking up a chat or system context by id - #1678

Open
takke1986 wants to merge 1 commit into
aws-samples:mainfrom
takke1986:fix/find-by-id-pagination
Open

fix(cdk): follow LastEvaluatedKey when looking up a chat or system context by id#1678
takke1986 wants to merge 1 commit into
aws-samples:mainfrom
takke1986:fix/find-by-id-pagination

Conversation

@takke1986

@takke1986 takke1986 commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Description of Changes

findChatById issued a single Query with a FilterExpression and ignored LastEvaluatedKey:

const res = await dynamoDbDocument.send(new QueryCommand({
  KeyConditionExpression: '#id = :id',
  FilterExpression: '#chatId = :chatId',
}));
if (!res.Items || res.Items.length === 0) return null;

DynamoDB reads up to 1 MB per page and applies FilterExpression after that read. For a user whose user#<id> partition exceeds 1 MB, the target chat can sit on a later page, so the function returns null even though the chat exists. This is what #1663 reports: heavy users stop being able to save new messages.

This PR extracts a small queryFirstMatch helper that follows LastEvaluatedKey until a match is found or the pages are exhausted, and uses it for findChatById.

findSystemContextById had the identical pattern (single Query + FilterExpression, no pagination), so it is fixed the same way. It is not covered by an existing issue; I found it while checking for other occurrences. A survey of repository.ts shows these were the only two — listChats already paginates, and the remaining queries do not use FilterExpression.

Compatibility: no signature or return-type change. The only difference is that a lookup which previously returned null for a large partition now returns the item. For partitions under 1 MB the behavior and the number of API calls are unchanged.

Checklist

  • Modified relevant documentation — n/a (internal data-access layer; the helper carries a comment explaining the DynamoDB behavior)
  • Verified operation in local environment
  • Executed npm run cdk:test — 45 tests / 15 snapshots passed, no snapshot differences

New unit tests in packages/cdk/test/lambda/repository.test.ts cover:

  • a match that only appears on a later page
  • LastEvaluatedKey being passed as ExclusiveStartKey on the following request
  • returning null once the pages are exhausted
  • not issuing a second query when the first page already matches

These tests fail against the previous implementation (4 of the 6 fail; the 2 that pass are the controls — a first-page match and a single-page miss), so they characterize the bug rather than the fix.

Also run:

  • npm run web:test — 278 passed
  • tsc --noEmit — no errors
  • eslint and prettier --check clean on all changed files

Related Issues

…ntext by id

findChatById issued a single Query with a FilterExpression and ignored
LastEvaluatedKey. DynamoDB reads up to 1 MB per page and applies
FilterExpression after that read, so for a user whose partition exceeds
1 MB the target chat can sit on a later page and the lookup returns null
even though the chat exists.

Extract a queryFirstMatch helper that follows LastEvaluatedKey until a
match is found or the pages are exhausted, and use it for findChatById.

findSystemContextById had the identical pattern and is fixed the same
way. A survey of repository.ts shows these were the only two functions
combining FilterExpression with no pagination; listChats already
paginates and the remaining queries do not filter.
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