Skip to content

fix(lambda-edge): avoid callback handler deprecation on NODEJS_24_X#4782

Merged
yusukebe merged 2 commits intohonojs:mainfrom
t0waxx:fix/lambda-edge-handler-arity
Mar 10, 2026
Merged

fix(lambda-edge): avoid callback handler deprecation on NODEJS_24_X#4782
yusukebe merged 2 commits intohonojs:mainfrom
t0waxx:fix/lambda-edge-handler-arity

Conversation

@t0waxx
Copy link
Contributor

@t0waxx t0waxx commented Mar 4, 2026

Closes #4772

Problem

handle() from hono/lambda-edge returns an async handler with Function.length === 3 because callback is a formal parameter. AWS Lambda NODEJS_24_X determines handler type by Function.length — when it's >= 3, the runtime treats it as a callback-style handler and throws Runtime.CallbackHandlerDeprecated.

Solution

Replace the three formal parameters (event, context, callback) with (event, ...args) and destructure context and callback internally. This reduces Function.length to 1 while preserving positional callback compatibility for older runtimes.

Before

return async (event: CloudFrontEdgeEvent, context?: CloudFrontContext, callback?: Callback) => {
  // Function.length === 3 → NODEJS_24_X treats as callback-style
}

After

return async (event: CloudFrontEdgeEvent, ...args: [CloudFrontContext?, Callback?]) => {
  const [context, callback] = args
  // Function.length === 1 → NODEJS_24_X treats as async-style
}

Tests Added

  • Verify handler.length <= 2 (regression test for the root cause)
  • Verify positional callback still works via handler(event, undefined, callback)
it('Should expose async handler arity compatible with NODEJS_24_X', () => {
  expect(handler.length).toBeLessThanOrEqual(2)
})

it('Should preserve positional callback compatibility', async () => {
  type Env = { Bindings: { callback: Callback } }
  const app = new Hono<Env>()
  const callback = vi.fn()

  app.get('/test-path', (c) => {
    c.env.callback?.(null, {
      status: '200',
      headers: {
        'x-test': [{ key: 'x-test', value: 'ok' }],
      },
    })
    return c.text('ok')
  })

  const handler = handle(app)
  await handler(cloudFrontEdgeEvent, undefined, callback)

  expect(callback).toHaveBeenCalledWith(null, {
    status: '200',
    headers: {
      'x-test': [{ key: 'x-test', value: 'ok' }],
    },
  })
})

Testing Note

  • This fix directly addresses the handler.length issue, which is the documented cause of the Runtime.CallbackHandlerDeprecated error in the NODEJS_24_X runtime.
  • Since this involves AWS infrastructure and I don't have an environment ready for immediate end-to-end testing, verification on a real deployment would be greatly appreciated.

The author should do the following, if applicable

  • Add tests
  • Run tests
  • bun run format:fix && bun run lint:fix to format the code

@codecov
Copy link

codecov bot commented Mar 5, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.47%. Comparing base (18cc595) to head (2e8dddb).
⚠️ Report is 6 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4782   +/-   ##
=======================================
  Coverage   91.47%   91.47%           
=======================================
  Files         177      177           
  Lines       11578    11579    +1     
  Branches     3368     3368           
=======================================
+ Hits        10591    10592    +1     
  Misses        986      986           
  Partials        1        1           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Member

@yusukebe yusukebe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@yusukebe
Copy link
Member

@t0waxx Thanks!

@yusukebe yusukebe merged commit 53b66ae into honojs:main Mar 10, 2026
20 checks passed
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.

handler() from hono/lambda-edge triggers Runtime.CallbackHandlerDeprecated on NODEJS_24_X

2 participants