Skip to content

MySQL migration: ADD COLUMN workspaces TEXT NOT NULL has no DEFAULT — fails on populated tables under strict mode #53

@TYRMars

Description

@TYRMars

Summary

The MySQL migration adds the workspaces column as TEXT NOT NULL with no DEFAULT, then backfills existing rows in a separate UPDATE. On a pre-existing populated projects table under strict SQL mode (MySQL 8 default STRICT_TRANS_TABLES), the ALTER TABLE … ADD COLUMN … TEXT NOT NULL itself errors because TEXT has no implicit default — so the migration fails before the backfill ever runs.

Details

  • crates/harness-store/src/mysql.rs:120-130:
    sqlx::query("ALTER TABLE projects ADD COLUMN workspaces TEXT NOT NULL")
        .execute(pool).await?;
    // Backfill so the NOT NULL constraint is satisfied for legacy rows.
    sqlx::query("UPDATE projects SET workspaces = '[]' WHERE workspaces IS NULL OR workspaces = ''")
        .execute(pool).await?;

The SQLite path does this safely with a default: sqlite.rs:120 ADD COLUMN workspaces TEXT NOT NULL DEFAULT '[]'. The MySQL path omits the DEFAULT, so the ADD COLUMN can't satisfy existing rows and aborts under strict mode (the backfill UPDATE is a no-op anyway since it runs after).

Impact

Breaks idempotent re-migration / upgrade on MySQL deployments that pre-date the workspaces column and have existing project rows. Severity: medium (MySQL only; depends on sql_mode, but strict is the MySQL 8 default).

Suggested fix

Add a default on the MySQL ADD COLUMN: ADD COLUMN workspaces TEXT NOT NULL DEFAULT ('[]') (expression default required for TEXT/BLOB in MySQL 8), or add the column as nullable, backfill, then MODIFY to NOT NULL.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions