[codex] Fix idle SQS polling in development#1
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a mechanism to disable SQS Lambda event-source mappings by default in development environments to prevent idle polling costs, while allowing them to be explicitly enabled via a new Terraform variable. It also configures 20-second long polling across all SQS queues, updates visibility timeouts, adds detailed batch-start logging to the Lambda handlers, and introduces a suite of Terraform tests to validate these behaviors. The review feedback highlights a potential runtime vulnerability in the SQS handlers (deliver-webhook, enrich-transcript, and start-transcription) where event.Records is accessed without verifying if it is defined or non-empty, and suggests adding early guard clauses to prevent potential TypeError exceptions.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| logInfo("sqs_worker_batch_started", { | ||
| worker: "deliver-webhook", | ||
| queueArn: event.Records[0]?.eventSourceARN, | ||
| batchSize: event.Records.length, | ||
| queueReceiveWaitTimeSeconds: 20, | ||
| idleBackoff: "managed-by-lambda-event-source-mapping" | ||
| }); |
There was a problem hiding this comment.
The handler currently accesses event.Records.length and event.Records[0] without verifying if event or event.Records is defined and non-empty. If the handler is invoked with an empty or malformed event payload (e.g., during manual testing or direct invocation), this will throw a runtime TypeError. Adding an early guard clause to validate the presence of records improves robustness and allows safe access to event.Records[0] without optional chaining.
if (!event?.Records || event.Records.length === 0) {
logWarn("sqs_worker_empty_or_invalid_event", { event });
return { batchItemFailures: [] };
}
logInfo("sqs_worker_batch_started", {
worker: "deliver-webhook",
queueArn: event.Records[0].eventSourceARN,
batchSize: event.Records.length,
queueReceiveWaitTimeSeconds: 20,
idleBackoff: "managed-by-lambda-event-source-mapping"
});| logInfo("sqs_worker_batch_started", { | ||
| worker: "enrich-transcript", | ||
| queueArn: event.Records[0]?.eventSourceARN, | ||
| batchSize: event.Records.length, | ||
| queueReceiveWaitTimeSeconds: 20, | ||
| idleBackoff: "managed-by-lambda-event-source-mapping" | ||
| }); |
There was a problem hiding this comment.
The handler currently accesses event.Records.length and event.Records[0] without verifying if event or event.Records is defined and non-empty. If the handler is invoked with an empty or malformed event payload (e.g., during manual testing or direct invocation), this will throw a runtime TypeError. Adding an early guard clause to validate the presence of records improves robustness and allows safe access to event.Records[0] without optional chaining.
if (!event?.Records || event.Records.length === 0) {
logWarn("sqs_worker_empty_or_invalid_event", { event });
return { batchItemFailures: [] };
}
logInfo("sqs_worker_batch_started", {
worker: "enrich-transcript",
queueArn: event.Records[0].eventSourceARN,
batchSize: event.Records.length,
queueReceiveWaitTimeSeconds: 20,
idleBackoff: "managed-by-lambda-event-source-mapping"
});| logInfo("sqs_worker_batch_started", { | ||
| worker: "start-transcription", | ||
| queueArn: event.Records[0]?.eventSourceARN, | ||
| batchSize: event.Records.length, | ||
| queueReceiveWaitTimeSeconds: 20, | ||
| idleBackoff: "managed-by-lambda-event-source-mapping" | ||
| }); |
There was a problem hiding this comment.
The handler currently accesses event.Records.length and event.Records[0] without verifying if event or event.Records is defined and non-empty. If the handler is invoked with an empty or malformed event payload (e.g., during manual testing or direct invocation), this will throw a runtime TypeError. Adding an early guard clause to validate the presence of records improves robustness and allows safe access to event.Records[0] without optional chaining.
if (!event?.Records || event.Records.length === 0) {
logWarn("sqs_worker_empty_or_invalid_event", { event });
return { batchItemFailures: [] };
}
logInfo("sqs_worker_batch_started", {
worker: "start-transcription",
queueArn: event.Records[0].eventSourceARN,
batchSize: event.Records.length,
queueReceiveWaitTimeSeconds: 20,
idleBackoff: "managed-by-lambda-event-source-mapping"
});
Summary
Root cause
The application has no direct
ReceiveMessageloop. Terraform created always-enabled Lambda SQS event-source mappings, so the Lambda service continuously polled empty development queues. The observed rate of roughly 8,640 empty receives per day matches that managed poller behavior.Lambda does not invoke handlers for empty receives, so application-side exponential backoff cannot run here. Disabling dev mappings is the stronger idle control: it stops receives entirely until
enable_sqs_workers=trueis set intentionally.Behavior
dev,development, andlocal: mappings default disabled1/5/1batch sizes remain because workers make sequential external calls within bounded Lambda timeoutsValidation
npm run buildnpm test(16 tests)npm audit --audit-level=high(0 vulnerabilities)npm run bundleterraform fmt -check -recursive .terraform validateterraform test(3 tests)git diff --check