fix(github-lambda): bundle via esbuild + inline resolveGitToken#182
Open
eipasteur wants to merge 1 commit into
Open
fix(github-lambda): bundle via esbuild + inline resolveGitToken#182eipasteur wants to merge 1 commit into
eipasteur wants to merge 1 commit into
Conversation
Two layered runtime regressions blocked /api/github/* on staging: 1. PR #176 migrated lambda/github from CommonJS to ESM but the Terraform packaging used npm_requirements + prefix_in_zip='shared'. The ESM resolver dereferenced '../shared/response.js' to /var/shared/... (one level above /var/task/), which doesn't exist, throwing ERR_MODULE_NOT_FOUND on every cold start. 2. shared/git-token.js is CommonJS and does require('@aws-sdk/client-ssm') at the module top level. esbuild bundles a CJS shim around it, but the Node.js ESM runtime rejects the resulting dynamic require: 'Dynamic require of @aws-sdk/client-ssm is not supported'. Fix: - terraform/modules/api/lambda/main.tf: switch github_lambda from npm_requirements to the build/:zip pattern (mirroring github_issues per PR #180), bumping runtime to nodejs24.x to match the esbuild --target=node24 the workspace already uses. - lambda/github/index.js: inline resolveGitToken locally, mirroring the exact pattern adopted by lambda/github-issues. shared/response.js remains imported because esbuild can statically bundle it without hitting a dynamic require (it has no top-level require of an external package). Validated end-to-end on staging: - terraform apply succeeded (no drift) - aws lambda invoke returns statusCode 200 with valid JSON body ({connected: false}) for /api/github/status - 153 unit tests across the repo continue to pass Closes the runtime regression introduced in #176.
This was referenced May 22, 2026
svozza
approved these changes
May 22, 2026
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.
Problem
Two layered runtime regressions blocked
/api/github/*endpoints in deployed environments:PR test(github): add unit tests for lambda/github handler #176 ("Migrate lambda/github to ESM") changed
require('./shared/...')toimport '../shared/response.js', but the Terraform packaging copiedshared/at the same level asindex.jsin the zip. At runtime, the ESM resolver dereferenced'../shared/response.js'to/var/shared/response.js— one level above/var/task/, which doesn't exist. Every cold start threwERR_MODULE_NOT_FOUND.shared/git-token.jsis CommonJS and usesrequire('@aws-sdk/client-ssm')at the module top level. Even after fixing the path, esbuild bundles a CJS shim that the Node.js ESM runtime rejects withDynamic require of "@aws-sdk/client-ssm" is not supported.Solution
Apply the same packaging pattern adopted for
lambda/github-issuesin #180:terraform/modules/api/lambda/main.tf: replacenpm_requirements + prefix_in_zip='shared'with thecommands + :zipesbuild build pattern; bump runtime tonodejs24.xto match the workspace--target=node24.lambda/github/index.js: inlineresolveGitTokenlocally (mirroring the pattern adopted bylambda/github-issues).shared/response.jscontinues to be imported from shared since it has no top-levelrequireof an external package and esbuild can statically bundle it.Validation
aws lambda invokereturnsstatusCode: 200with valid JSON{"connected": false}/api/github/statusreturns proper JSON 401 (was returning HTML 200 before)Why inline
resolveGitTokenrather than refactorshared/10+ other CJS lambdas import
shared/responseandshared/git-token. Migrating shared/ to ESM would force a coordinated rewrite of all of them, well beyond the scope of this fix. Inlining mirrors the pragmatic precedent set by #180.Closes the regression introduced in #176.