Skip to content

fix(lambda): build the layer again after a failed build - #237

Open
TheHolyWaffle wants to merge 2 commits into
floydspace:mainfrom
TheHolyWaffle:fix/lambda-rebuild-after-failed-build
Open

TheHolyWaffle wants to merge 2 commits into
floydspace:mainfrom
TheHolyWaffle:fix/lambda-rebuild-after-failed-build

Conversation

@TheHolyWaffle

Copy link
Copy Markdown

Closes #235.

A ManagedRuntime keeps a failed layer build, so a transient failure during a Lambda cold start (a database still scaling, a throttled Secrets Manager or SSM call) failed every later invocation of the container until AWS recycled it.

Changes

  • make, stream and streamFromHttpApi run on a new internal runner (internal/runtime.ts). When the runtime's build fails, the runner disposes that runtime and replaces it with a fresh one, so the next invocation builds the layer again. Disposing also closes the failed build's scope, which evicts it from a shared memoMap.
  • makeWebHandler builds the router with HttpRouter.toHttpEffect and serves it with HttpEffect.toWebHandlerWith, instead of HttpRouter.toWebHandler. toWebHandler starts its own build and rejects every request when that build fails, while the WebHandler layer around it still succeeded, so the runner never saw the failure. A failed router build now fails the WebHandler layer. The default HttpMiddleware.logger and the middleware option compose as toWebHandler composes them.
  • LambdaRuntime.fromLayer keeps its signature and behaviour; its signal handling moved into the internal module so the runner can share it.

Behaviour change

makeWebHandler's error channel now carries the router layer's error, since the build happens there.

Tests

Two new tests, both failing on main and passing here:

  • LambdaHandler.make with a layer that fails its first build: the first invocation rejects, later ones succeed, and the layer is built twice.
  • LambdaHandler.fromHttpApi with an API layer that fails its first build: the first invocation rejects, the second answers 200.

I also ran the repro from #235 against the packed dist:

invocation 1: rejected transient (builds=1)
invocation 2: resolved ok (builds=2)
invocation 3: resolved ok (builds=2)

@changeset-bot

changeset-bot Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

馃 Changeset detected

Latest commit: b5f9efd

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@effect-aws/lambda Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

A ManagedRuntime keeps a failed layer build, so a transient failure during a
cold start failed every later invocation of the container. The handlers now
dispose a runtime whose build failed, which also evicts the failure from a
shared memoMap, and the next invocation builds the layer again.

makeWebHandler builds the router itself, so a failed router build fails the
WebHandler layer instead of every request inside HttpRouter.toWebHandler.

Closes floydspace#235
@TheHolyWaffle
TheHolyWaffle force-pushed the fix/lambda-rebuild-after-failed-build branch from 9d6def4 to 1bd5443 Compare October 3, 2026 08:43
HttpRouter.toHttpEffect builds in a fork of the memo map, so layers built
for a fromHttpApi handler weren't shared with other handlers using the same
memoMap. makeWebHandler now builds the router directly in options.memoMap.

This branch has not been deployed

No deployments
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.

LambdaHandler.make keeps a failed layer build for the container's lifetime

1 participant