-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Description
Bug Report: Duplicate 'extend' identifier in Rails Admin JavaScript with Rails 7 + jsbundling-rails (esbuild)
Environment
- Rails: 7.1
- Rails Admin: 3.3.0 (also tested with 3.2.x - same issue)
- Ruby: 3.1.2
- JavaScript Bundler: jsbundling-rails with esbuild
- Asset Pipeline: Sprockets 4.2.1
- Other relevant gems: turbo-rails, stimulus_reflex, tailwindcss-rails
Description
Rails Admin filtering and sorting features are completely non-functional due to a JavaScript syntax error. The duplicate identifier error occurs in Rails Admin's own compiled JavaScript file, preventing all JavaScript-dependent features from working.
Error Message
Uncaught SyntaxError: Identifier 'extend' has already been declared
at application-61ed2d5f1ba7beeb653ee0e0858a724970b2294197a7109d85a35dae7ee7426d.js:45348:7
The error occurs in the compiled Rails Admin JavaScript file served by Sprockets:
http://localhost:3000/assets/rails_admin/application-61ed2d5f1ba7beeb653ee0e0858a724970b2294197a7109d85a35dae7ee7426d.js
CRITICAL FINDING: Only Affects Rails 6→7 Upgrades
This bug does NOT occur in fresh Rails 7 apps. The duplicate extend declaration only appears in applications that were upgraded from Rails 6 to Rails 7.
This significantly narrows down the root cause to migration artifacts or legacy configurations from Rails 6.
Steps to Reproduce
IMPORTANT: This requires a Rails 6 app upgraded to Rails 7. Fresh Rails 7 apps do NOT exhibit this issue.
- Start with a Rails 6.x app using jsbundling-rails (esbuild)
- Upgrade the app to Rails 7.1
- Have
rails_admingem in Gemfile - Run
bundle install - Configure
config.asset_source = :sprocketsinconfig/initializers/rails_admin.rb - Start Rails server
- Navigate to
/admin - Open browser DevTools Console
- Try to use filter or sort features
Contrast: Creating a fresh Rails 7.1 app and installing Rails Admin does NOT produce this error.
Expected Behavior
- Rails Admin dashboard should load without JavaScript errors
- Filter button should open filter panel
- Column headers should be sortable
- All JavaScript-dependent features should work
Actual Behavior
- JavaScript console shows:
Uncaught SyntaxError: Identifier 'extend' has already been declared - Filter buttons are visible but non-functional (clicking does nothing)
- Sort functionality is broken
- All JavaScript features fail silently
Investigation Findings
1. Only Rails Admin JS loads (verified via View Source)
The HTML source shows only Rails Admin's JavaScript loading:
<script src="http://localhost:3000/assets/rails_admin/application-[hash].js" defer="defer" data-turbo-track="reload"></script>The main application JavaScript bundle from esbuild does NOT load on admin pages.
2. Duplicate is INSIDE Rails Admin's compiled file
The duplicate extend identifier is within the Rails Admin JavaScript file itself, not caused by multiple files loading or conflicts with application JavaScript.
3. Consistent file hash across recompilations
Despite clearing all caches and forcing recompilation, the same file hash appears, suggesting:
- The compilation process consistently produces the duplicate
- OR the source files contain duplicates that get compiled
4. No external conflicts
- Rails Admin is only in
Gemfile(not inpackage.json) - No jQuery or Bootstrap conflicts
- Application JavaScript successfully isolated from admin pages
Solutions Attempted (All Failed)
- asset_source configurations: Tried
:sprockets,:webpack,:importmap, and auto-detection - Custom layout override: Created custom Rails Admin layout to prevent application.js loading
- Asset manifest modifications: Added/removed explicit Rails Admin asset links
- Cache clearing: Deleted
public/assets/,tmp/cache/, forced asset recompilation - Version downgrade: Tested with Rails Admin 3.2.x, 3.1.x
- Parent controller override: Set
config.parent_controller = 'ActionController::Base'
Configuration Files
config/initializers/rails_admin.rb
RailsAdmin.config do |config|
config.asset_source = :sprockets
config.authenticate_with do
warden.authenticate! scope: :user
end
config.authorize_with do
if !current_user || !current_user.superadmin?
redirect_to(main_app.root_path, alert: "You are not permitted to view this page")
end
end
# ... model configurations
endGemfile (relevant parts)
gem 'rails', '7.1'
gem 'jsbundling-rails'
gem 'sassc-rails'
gem 'rails_admin'
gem 'turbo-rails'esbuild.config.mjs
const entryPoints = ["application.js"]
const config = {
absWorkingDir: path.join(process.cwd(), "app/javascript"),
bundle: true,
entryPoints: entryPoints,
minify: process.env.RAILS_ENV == "production",
outdir: path.join(process.cwd(), "app/assets/builds"),
plugins: [rails()],
sourcemap: process.env.RAILS_ENV != "production"
}Potential Root Cause
Since this only affects Rails 6→7 upgrades and NOT fresh Rails 7 apps, the root cause is likely related to migration artifacts or legacy configurations from Rails 6.
Likely Causes (Rails 6→7 Specific):
-
Legacy Asset Pipeline Configuration
- Rails 6 apps often have Sprockets-specific settings in
config/application.rbandconfig/initializers/assets.rb - These configurations may conflict with Rails 7's updated asset handling
- Fresh Rails 7 apps have cleaner, modern asset configurations
- Rails 6 apps often have Sprockets-specific settings in
-
Dual Asset Pipeline (Sprockets + esbuild)
- Upgraded apps may have both Rails 6-style Sprockets config AND Rails 7-style esbuild
- This dual configuration might cause Rails Admin assets to be processed incorrectly
- Fresh Rails 7 apps typically use only one asset approach
-
Initializer Load Order Changes
- Rails 6→7 upgrades often accumulate additional initializers (like custom Rails Admin fixes)
- The presence of extra initializers can change initialization order
- This may cause Rails Admin to be extended or initialized multiple times
-
Framework Defaults Files
- Upgraded apps have
config/initializers/new_framework_defaults_7_1.rbwith commented-out settings - These gradual migration settings might interact poorly with Rails Admin asset compilation
- Fresh Rails 7 apps don't have these migration files
- Upgraded apps have
-
Legacy node_modules Asset Paths
- Rails 6 apps often added
node_modulestoconfig.assets.paths - This legacy configuration might cause asset resolution conflicts in Rails 7
- Rails 6 apps often added
Evidence from Upgraded App:
- Presence of
config/initializers/new_framework_defaults_7_1.rb(only exists in upgraded apps) - Custom
config/initializers/rails_admin_asset_fix.rb(workaround created during migration) - Mixed asset configuration with both Sprockets and esbuild settings
- Legacy asset path configurations (
node_modulesin asset paths)
Files to Investigate in Upgraded Apps:
If you're debugging this issue, check these files for Rails 6 legacy configurations:
config/application.rb- Look forconfig.assets.*settingsconfig/initializers/assets.rb- Check fornode_modulesin asset paths or custom precompile settingsconfig/initializers/new_framework_defaults_*.rb- Migration transition files- Any custom
config/initializers/rails_admin_*.rbfiles created as workarounds config/environments/development.rb- Asset compilation settings
Impact
This completely breaks Rails Admin's JavaScript functionality in Rails 6→7 upgraded apps using jsbundling-rails with esbuild, making the gem unusable for its primary purpose (admin CRUD operations with filtering/sorting).
Scope: This affects teams upgrading from Rails 6 to Rails 7, which is a common migration path. Fresh Rails 7 apps are unaffected.
Workaround
None found. Users are forced to either:
- Switch to a different admin panel (Avo, Motor Admin, ActiveAdmin)
- Deactivate Trix/ActionText (and thus lose rich_text support)
Request
Could the Rails Admin team:
- Test with a Rails 6→7 upgraded app (not a fresh Rails 7 app, as fresh apps don't exhibit this bug)
- Investigate how legacy asset configurations from Rails 6 might cause duplicate
extenddeclarations during Sprockets compilation - Provide guidance on which Rails 6 configurations should be removed/updated for Rails Admin to work correctly in Rails 7
- Consider adding a "Upgrading from Rails 6" section to documentation addressing this issue
- Potentially add a diagnostic that detects problematic Rails 6 legacy configurations and warns users
Additional Context
We spent approximately 4+ hours investigating this issue and trying various solutions. Every approach failed to resolve the duplicate identifier error.
The issue appears to be in how Sprockets compiles Rails Admin's JavaScript when used in a Rails 6→7 upgraded app with jsbundling-rails, likely due to conflicting asset pipeline configurations left over from the Rails 6 era.
This is blocking our Rails 7 upgrade and we're currently evaluating alternative admin panels (Avo, Motor Admin) as workarounds.