gastownhall/beads · error

ensuring local_metadata: %w

Error message

ensuring local_metadata: %w

What it means

setAuxRekeyInProgress records the clone-local crash sentinel for an aux-row rekey pass in the dolt-ignored local_metadata table. Because local_metadata is dolt-ignored, a fresh clone whose main migration cursor is already past migration 0029 does not have the table, so this function first runs CREATE TABLE IF NOT EXISTS with 0029's DDL. This error wraps any failure of that CREATE TABLE, meaning the sentinel could not be laid down and the rekey rewrite has not started.

Source

Thrown at internal/storage/schema/aux_row_id_backfill.go:121

		keys[i] = pass.sentinelKey
	}
	var n int
	if err := db.QueryRowContext(ctx,
		fmt.Sprintf("SELECT COUNT(*) FROM local_metadata WHERE `key` IN (%s)", strings.Join(placeholders, ", ")),
		keys...).Scan(&n); err != nil {
		return false, err
	}
	return n > 0, nil
}

func setAuxRekeyInProgress(ctx context.Context, db DBConn, sentinelKey string) error {
	// local_metadata is dolt-ignored, hence clone-local: a fresh clone whose
	// main cursor is already past 0029 does not have the table (the migration
	// will not re-run) until EnsureIgnoredTables recreates it. Create it here
	// with 0029's DDL — its dolt_ignore pattern is committed history, so the
	// sentinel stays clone-local.
	if _, err := db.ExecContext(ctx, "CREATE TABLE IF NOT EXISTS local_metadata (`key` VARCHAR(255) PRIMARY KEY, value TEXT NOT NULL DEFAULT '')"); err != nil {
		return fmt.Errorf("ensuring local_metadata: %w", err)
	}
	_, err := db.ExecContext(ctx,
		"REPLACE INTO local_metadata (`key`, value) VALUES (?, '1')",
		sentinelKey)
	return err
}

func clearAuxRekeyInProgress(ctx context.Context, db DBConn, sentinelKey string) error {
	_, err := db.ExecContext(ctx,
		"DELETE FROM local_metadata WHERE `key` = ?",
		sentinelKey)
	return err
}

// auxRekeyTable describes one table covered by the re-key. columns is the
// frozen SELECT list of every non-id column, in creation order, with datetime
// columns CAST to CHAR server-side so the scanned text is identical across
// drivers and connection settings.

View on GitHub (pinned to 71377f2769)

Solutions

  1. Unwrap and read the driver error — check connectivity and re-run; the pass is resumable and the rewrite has not started.
  2. Grant the database user CREATE privilege (or run migrations as an admin) so local_metadata can be created.
  3. Check for a conflicting non-ignored object named local_metadata and drop/rename it.
  4. Run `bd doctor` / re-open the database to let EnsureIgnoredTables recreate dolt-ignored tables, then retry MigrateUp.

Example fix

// before
// app user lacks DDL rights; CREATE TABLE IF NOT EXISTS local_metadata fails

// after
-- as admin, once per clone:
CREATE TABLE IF NOT EXISTS local_metadata (`key` VARCHAR(255) PRIMARY KEY, value TEXT NOT NULL DEFAULT '');
GRANT CREATE ON mydb.* TO 'beads'@'%';
Defensive patterns

Strategy: retry

Validate before calling

// before migrating, verify the clone can create the ignored table:
var canCreate int
_ = db.QueryRow(`SELECT COUNT(*) FROM INFORMATION_SCHEMA.SCHEMA_PRIVILEGES
 WHERE TABLE_SCHEMA = DATABASE() AND PRIVILEGE_TYPE = 'CREATE'`).Scan(&canCreate)
if canCreate == 0 { return errors.New("migration user cannot CREATE local_metadata") }

Try / catch

if err := runMigration(); err != nil {
    if strings.Contains(err.Error(), "ensuring local_metadata") {
        return fmt.Errorf("storage unavailable or lacking DDL privilege; fix and re-run migration (resumable): %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Running MigrateUp on a fresh or partially-synced Dolt clone where local_metadata is missing and the CREATE TABLE IF NOT EXISTS statement fails — typically due to connection loss, permissions (no CREATE privilege), read-only replica, or a conflicting object named local_metadata.

Common situations: Upgrading a cloned beads repository (bd pull/clone then run) where the ignored table has not been recreated by EnsureIgnoredTables; running with a DB user lacking DDL privileges; a crashed/terminated earlier migration leaving locks; storage-backend version mismatch.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/1845ba4e914899c2. Report an issue: GitHub.