Skip to content

Conversation

@sosukesuzuki
Copy link
Contributor

@sosukesuzuki sosukesuzuki commented Aug 29, 2025

Context: oven-sh/bun#22213

Starting from Bun 1.2.21, namespace objects no longer inherit from Object.prototype (oven-sh/bun#21984). This change was made to comply with the ECMAScript specification.

This caused plugin.constructor to become undefined when executing app.use(import("plugin")), resulting in a TypeError being thrown when accessing plugin.constructor.name.

This PR fixes the issue by using optional chaining to check that plugin.constructor exists.

This change is verified by four existing tests, so no additional tests are included (running the following tests with Bun 1.2.21 will fail):

  • Modules > inline import
  • Modules > import
  • Modules > inline import non default
  • Modules > handle deferred import

Summary by CodeRabbit

  • Bug Fixes

    • Improved robustness of plugin handling in Elysia.use to prevent rare runtime errors when a plugin lacks expected constructor metadata.
    • Safely detects plugin types even when certain internal properties are undefined, reducing edge-case crashes.
  • Chores

    • No changes to public APIs or exported signatures.

@coderabbitai
Copy link

coderabbitai bot commented Aug 29, 2025

Walkthrough

Optional chaining added to constructor name checks in src/index.ts to safely access plugin.constructor?.name when detecting 'Elysia' and '_Elysia' within Elysia.use. No other logic or APIs changed.

Changes

Cohort / File(s) Summary of Changes
Type guard adjustments
src/index.ts
Replaced strict plugin.constructor.name checks with plugin.constructor?.name for 'Elysia' (two occurrences) and '_Elysia' branches to avoid runtime errors when constructor is missing. No public API changes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I twitch my ears at cautious code,
A gentle hop where nulls once strode.
With ?. I tread—no crashes there—
Soft paws on types, with safer care.
Elysian paths now clearly shown,
Bugs stay burrowed; I’ve overthrown. 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbit in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbit in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbit gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbit read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbit help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbit ignore or @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbit summary or @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbit or @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@sosukesuzuki sosukesuzuki marked this pull request as ready for review August 29, 2025 03:02
@sosukesuzuki sosukesuzuki changed the title fix: check if the plugin constructor exists fix: check if the plugin.constructor exists Aug 29, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7d52294 and 7e61c4d.

📒 Files selected for processing (1)
  • src/index.ts (2 hunks)
🔇 Additional comments (1)
src/index.ts (1)

4007-4011: Good defensive fix: optional chaining prevents TypeError on Bun 1.2.21.

This fallback check is safe and keeps behavior unchanged otherwise.

Comment on lines +4018 to 4020
if (plugin.constructor?.name === 'Elysia')
return this._use(plugin.default)

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Bug: checking the module namespace object instead of the default export.

When handling an ES module with a default Elysia instance, this should inspect plugin.default.constructor?.name, not plugin.constructor?.name.

Apply:

- if (plugin.constructor?.name === 'Elysia')
+ if (plugin.default?.constructor?.name === 'Elysia')
   return this._use(plugin.default)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (plugin.constructor?.name === 'Elysia')
return this._use(plugin.default)
if (plugin.default?.constructor?.name === 'Elysia')
return this._use(plugin.default)
🤖 Prompt for AI Agents
In src/index.ts around lines 4018 to 4020, the code is checking
plugin.constructor?.name which inspects the module namespace object for ESM
modules instead of the default export; change the conditional to inspect
plugin.default.constructor?.name and call this._use(plugin.default) for ESM
default exports, while preserving the existing path for non-ESM plugins (i.e.,
first check plugin.constructor?.name === 'Elysia' then fall back to
plugin.default?.constructor?.name === 'Elysia'); also guard against
plugin.default being undefined before accessing its constructor.

Comment on lines +4021 to 4023
if (plugin.constructor?.name === '_Elysia')
return this._use(plugin.default)

Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Same bug for '_Elysia' branch; also targets the wrong object.

This should also read from plugin.default.

Apply:

- if (plugin.constructor?.name === '_Elysia')
+ if (plugin.default?.constructor?.name === '_Elysia')
   return this._use(plugin.default)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (plugin.constructor?.name === '_Elysia')
return this._use(plugin.default)
if (plugin.default?.constructor?.name === '_Elysia')
return this._use(plugin.default)
🤖 Prompt for AI Agents
In src/index.ts around lines 4021 to 4023, the '_Elysia' branch currently checks
plugin.constructor?.name (the wrong object) and must instead inspect the
exported default; change the condition to read plugin.default?.constructor?.name
=== '_Elysia' and have it call this._use(plugin.default) so both the check and
the argument target the actual default export.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Aug 30, 2025

Open in StackBlitz

npm i https://pkg.pr.new/elysiajs/elysia@1365

commit: 7e61c4d

@SaltyAom SaltyAom merged commit 1fb90d4 into elysiajs:main Aug 30, 2025
3 checks passed
@sosukesuzuki sosukesuzuki deleted the check-for-namespace branch August 31, 2025 02:02
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.

2 participants