Quick summary
The push SQL export drops index prefix lengths (SUB_PART) when reconstructing PRIMARY KEY clauses. A table with a prefixed primary key on a TEXT column — e.g. PRIMARY KEY (session_id(100)) on a mediumtext column — exports as PRIMARY KEY (session_id), which MySQL/MariaDB reject with ERROR 1170 (42000): BLOB/TEXT column used in key specification without a key length. The remote import aborts and Studio shows only the generic "The database failed to import on the live site."
The prefix IS recorded correctly on pull: _wp_sqlite_mysql_information_schema_statistics contains SUB_PART = 100 for the column. The bug is emission-only: in the CREATE TABLE reconstruction (sqlite-database-integration 3.0.0-rc.8, class-wp-mysql-on-sqlite.php), the non-PRIMARY key branch appends sprintf('(%d)', $column['SUB_PART']), but the PRIMARY KEY branch maps columns through quote_mysql_identifier() only and never emits SUB_PART.
In my case the table came from the miniOrange 2FA plugin (wp_mo2f_user_login_info), pulled from a production WordPress.com site. Any site pulled from production with a prefixed-TEXT primary key in any table cannot be pushed back.
Steps to reproduce
- Create a Studio site and add a table with a prefixed TEXT primary key, e.g. via
wp eval '$GLOBALS["wpdb"]->query("CREATE TABLE wp_repro (id MEDIUMTEXT NOT NULL, PRIMARY KEY (id(100)))");' (or pull a production site containing such a table).
- Export the database (or push to a connected WordPress.com site with Database checked).
- Inspect the exported SQL: the CREATE TABLE contains
PRIMARY KEY (id) with no (100) prefix.
- Importing that SQL into MariaDB fails:
ERROR 1170 (42000): BLOB/TEXT column 'id' used in key specification without a key length. Pushes fail with the generic database-import error.
Verified by replaying the exact exported file into MariaDB 10.6 (default sql_mode, utf8mb4 client): the import aborts at the affected statement; after removing the affected table, the same export imports cleanly.
What you expected to happen
PRIMARY KEY reconstruction should emit SUB_PART like the non-primary branch does, producing PRIMARY KEY (id(100)). Studio should also surface the underlying SQL error instead of the generic message.
What actually happened
Every push with Database checked fails with "The database failed to import on the live site. Review your database and try again." The server-side web logs show the Jetpack import helper streaming the import and returning HTTP 500 at the affected statement, with no actionable error surfaced in the app.
App or CLI?
Studio App
Version
1.20.0
Impact
One
Available workarounds?
No and the app is unusable. However, "No" is misleading, but it might as well be "no" as I couldn't find the cause of the issue without a lot of back-and-forth with Claude.
Only workaround is to drop or restructure the affected table locally (mine belonged to an uninstalled plugin), then push. Finding the table requires manually replaying the export against a local MariaDB, since the app does not surface the failing statement.
Platform
Mac
Architecture
ARM64 (Apple Silicon, Windows or Linux on ARM)
Logs or notes
- Studio 1.20.0 (commit e234e94), macOS 26.6.1, sqlite-database-integration 3.0.0-rc.8, local PHP 8.4
- Remote: WordPress.com Atomic production site
- Related reports filed for two other push failure modes encountered on the same site (invalid exported collation; non-atomic file sync fataling the import bootstrap)
Quick summary
The push SQL export drops index prefix lengths (SUB_PART) when reconstructing PRIMARY KEY clauses. A table with a prefixed primary key on a TEXT column — e.g.
PRIMARY KEY (session_id(100))on amediumtextcolumn — exports asPRIMARY KEY (session_id), which MySQL/MariaDB reject withERROR 1170 (42000): BLOB/TEXT column used in key specification without a key length. The remote import aborts and Studio shows only the generic "The database failed to import on the live site."The prefix IS recorded correctly on pull:
_wp_sqlite_mysql_information_schema_statisticscontainsSUB_PART = 100for the column. The bug is emission-only: in the CREATE TABLE reconstruction (sqlite-database-integration 3.0.0-rc.8,class-wp-mysql-on-sqlite.php), the non-PRIMARY key branch appendssprintf('(%d)', $column['SUB_PART']), but the PRIMARY KEY branch maps columns throughquote_mysql_identifier()only and never emits SUB_PART.In my case the table came from the miniOrange 2FA plugin (
wp_mo2f_user_login_info), pulled from a production WordPress.com site. Any site pulled from production with a prefixed-TEXT primary key in any table cannot be pushed back.Steps to reproduce
wp eval '$GLOBALS["wpdb"]->query("CREATE TABLE wp_repro (id MEDIUMTEXT NOT NULL, PRIMARY KEY (id(100)))");'(or pull a production site containing such a table).PRIMARY KEY (id)with no(100)prefix.ERROR 1170 (42000): BLOB/TEXT column 'id' used in key specification without a key length. Pushes fail with the generic database-import error.Verified by replaying the exact exported file into MariaDB 10.6 (default sql_mode, utf8mb4 client): the import aborts at the affected statement; after removing the affected table, the same export imports cleanly.
What you expected to happen
PRIMARY KEY reconstruction should emit SUB_PART like the non-primary branch does, producing
PRIMARY KEY (id(100)). Studio should also surface the underlying SQL error instead of the generic message.What actually happened
Every push with Database checked fails with "The database failed to import on the live site. Review your database and try again." The server-side web logs show the Jetpack import helper streaming the import and returning HTTP 500 at the affected statement, with no actionable error surfaced in the app.
App or CLI?
Studio App
Version
1.20.0
Impact
One
Available workarounds?
No and the app is unusable. However, "No" is misleading, but it might as well be "no" as I couldn't find the cause of the issue without a lot of back-and-forth with Claude.
Only workaround is to drop or restructure the affected table locally (mine belonged to an uninstalled plugin), then push. Finding the table requires manually replaying the export against a local MariaDB, since the app does not surface the failing statement.
Platform
Mac
Architecture
ARM64 (Apple Silicon, Windows or Linux on ARM)
Logs or notes