# Add a Dead Letter Queue to a Lambda in AWS CDK from a Linear Issue

Yes. An agent picks up the Linear issue, gives each Lambda an SQS dead letter queue and a CloudWatch alarm, with assertion tests, and opens a pull request.

[Run this on Rush](https://cloud.getrush.ai/run/add-dlq/aws-cdk/), in a Project that has your repository.

## What the agent does

The run starts from the repository URL in `resources`: the agent clones it into its own cloud sandbox and opens the TypeScript example the issue names. In `aws-samples/aws-cdk-examples`, that example is `typescript/api-cors-lambda-crud-dynamodb/`. Its `package.json` depends on `aws-cdk-lib` 2.262.1 and the `aws-cdk` CLI 2.1133.0, builds with `tsc`, and already lists Jest 30 with `@swc/jest`, though it has no `test` script yet. `jest.config.js` matches `**/*.test.ts` and loads `aws-cdk-lib/testhelpers/jest-autoclean`.

The stack in `index.ts` defines five `NodejsFunction` Lambdas on Node.js 24: get-one, get-all, create, update-one and delete-one, each bundling from `lambdas/*.ts` with the DynamoDB table name in the environment. None of them set `deadLetterQueue` or `deadLetterQueueEnabled` today, and there are no CloudWatch alarms in the file. API Gateway CORS helpers at the bottom of `index.ts` stay out of scope.

The agent gives each function its own SQS queue as a dead letter queue with a modest `maxReceiveCount`, using `aws-cdk-lib/aws-sqs` and the Lambda `deadLetterQueue` property on `NodejsFunction`. For every queue it adds a CloudWatch alarm on `ApproximateNumberOfMessagesVisible` so a depth above zero pages someone. The five Lambdas keep their existing DynamoDB grants and routes on `/items`.

Proving it means assertion tests the example never shipped. The agent adds a `test` script that runs Jest, writes a `*.test.ts` that synthesizes `ApiLambdaCrudDynamoDBStack`, and uses `annotations` / template matchers from `aws-cdk-lib/assertions` to require five SQS queues, five Lambdas with `DeadLetterConfig`, and five alarms. Then it runs `npm test` and `npx cdk synth` inside the example directory.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "A Linear issue labeled agent says: \"Add a Dead Letter Queue to a Lambda in AWS CDK. In typescript/api-cors-lambda-crud-dynamodb, give each Lambda an SQS dead letter queue and a CloudWatch alarm on its depth, with assertion tests.\" Do the work in this repository, add tests for it, run npm test and cdk synth in the example, and open a pull request that links back to the issue.",
  "resources": [
    {
      "url": "https://github.com/your-org/your-app"
    }
  ]
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

What comes back is a pull request. Its diff updates `typescript/api-cors-lambda-crud-dynamodb/index.ts` with the queues and alarms, adds a Jest test file beside it, and wires a `test` script in that example's `package.json`. The description quotes the issue and links back to it.

The checks on the pull request run `npm test` and `cdk synth` in the example. A reviewer reads the template assertions for one DLQ and one alarm per Lambda, confirms `maxReceiveCount` is set, and confirms the DynamoDB table and API routes are unchanged. Other language folders under `typescript/` are left alone.

The session read keeps the record behind the pull request: npm install, the Jest run and the synth output. Anyone who questions a missing `DeadLetterConfig` can see the assertion that failed before the agent fixed it.

## Run it on every Linear issue labelled agent

The Project's automation turns the label into the run. In the console, add an automation with a Linear trigger on `linear.issue.labeled` filtered to the `agent` label and this prompt; each labelled CDK reliability issue starts its own run in its own sandbox and opens its own pull request on the examples repository.

If the automation is not wanted, a small server can do the same: receive Linear's issue webhook, put the issue text into `input`, and POST to `/o/{org}/sessions` with the aws-cdk-examples repository in `resources`. A `run.completed` webhook on the API key posts the pull request when synth and tests pass.

## Why run it on Rush?

On a laptop this job needs Node for the example's toolchain, a CDK bootstrap-free synth, and enough patience to install `aws-cdk-lib` before Jest will load the assertion helpers. Each run on Rush boots its own sandbox with that already in reach, runs `npm test` and `cdk synth` itself, and keeps every command and its output.

DLQ work is easy to postpone until the first silent failure in production. Labelling the issue starts a sandbox that adds the queues, alarms and assertions without blocking whoever is mid-deploy on another stack in the same monorepo of examples.

## Frequently asked questions

### Does every Lambda share one DLQ?

No. The agent gives each of the five NodejsFunction constructs its own queue and its own depth alarm, so a failing create does not hide behind a delete backlog.

### Is cdk bootstrap required in the sandbox?

No. The prompt asks for `cdk synth` and `npm test`, which only need the TypeScript app to compile and emit a template. No account credentials are required for that path.

### The example had Jest but no test script. What gets added?

A `test` script that runs Jest with the existing `jest.config.js`, plus a new `*.test.ts` that synthesizes the stack. DevDependencies for Jest are already listed in `package.json`.

### Will API Gateway routes change?

No. `/items` and `/items/{id}` keep the same methods and CORS OPTIONS mock. Only the Lambda functions gain dead letter configuration and alarms.
