Skip to content

fix: preserve class names in production builds for TypeORM migrations#781

Open
f1sherman wants to merge 1 commit intoBlueBubblesApp:developmentfrom
f1sherman:fix/webpack-migration-classnames
Open

fix: preserve class names in production builds for TypeORM migrations#781
f1sherman wants to merge 1 commit intoBlueBubblesApp:developmentfrom
f1sherman:fix/webpack-migration-classnames

Conversation

@f1sherman
Copy link
Copy Markdown

Summary

Fix a latent bug where TypeORM migrations fail in production builds due to webpack's Terser minification mangling class names.

Problem

TypeORM's MigrationExecutor parses the timestamp from migration class names at runtime (e.g., WebhookChatGuids1710720000000 → timestamp 1710720000000). In production builds, webpack's default Terser config minifies class names (e.g., ei), causing TypeORM to throw:

TypeORMError: ei migration name is wrong. Migration class name should have a JavaScript timestamp appended.

The server hangs at "Initializing server database..." and never starts.

Why it hasn't been noticed

The existing release builds have the same minification behavior, but it doesn't surface because:

  1. Fresh installs: config.db doesn't exist, so shouldSync = true, which sets migrationsRun: false — TypeORM uses synchronize: true instead of running migrations.
  2. Subsequent launches: The DB already matches the schema, so there are no pending migrations.

The bug only triggers when a new migration is added and the app is upgraded on a machine that already has config.db.

Fix

Configure Terser to preserve class names in webpack.main.prod.config.js:

new TerserPlugin({
    terserOptions: {
        keep_classnames: true,
    },
})

terser-webpack-plugin is already available as a transitive dependency of webpack 5 — no new dependencies needed. Bundle size impact is minimal.

Alternatives considered

  • Scoped keep_classnames (migration files only): Terser doesn't support per-file class name preservation without a more complex setup
  • optimization.minimize: false: Fixes the issue but disables all minification
  • Setting name property on migration classes: TypeORM checks the class name, not a name property, for timestamp parsing

Webpack's Terser minification mangles class names in production builds,
which breaks TypeORM's migration runner — it parses the timestamp from
the class name to determine migration identity and ordering. Configure
Terser with keep_classnames: true to prevent this.

The bug hasn't surfaced before because existing installs either use
synchronize (fresh install) or have no pending migrations (subsequent
launches). It only triggers when a new migration is added and the app
is upgraded on a machine with an existing config.db.
@f1sherman
Copy link
Copy Markdown
Author

I ran into this bug while testing #780. Let me know if I did something wrong, thank you!

@zlshames
Copy link
Copy Markdown
Member

Thanks for the contribution! Just FYI, I'm not ignoring this by any means. My priorities are with the Android/Desktop app complete rewrite and this is next on my list.

The rewrite is going well, but it's a lot of refactors and migrations, so it may take some time. I plan to do a beta/alpha in the near future. But just don't think this is being ignored. It's not!

@f1sherman
Copy link
Copy Markdown
Author

@zlshames sounds great, thanks so much! Just let me know if I need to change anything due to the re-write.

@Clauber
Copy link
Copy Markdown

Clauber commented Apr 4, 2026

Any way this PR can be merged for the current version @zlshames ?

@zlshames
Copy link
Copy Markdown
Member

zlshames commented Apr 4, 2026

Any way this PR can be merged for the current version @zlshames ?

Is there a high urgency to it? I'm currently spending all my time working on the App rewrite. It's almost done, I'm just ironing out a few things before releasing a beta for it. Then I plan to work on all of the PRs and other work items for the server

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.

3 participants