gastownhall/beads · error

deduplicating wisp_dependencies before the 0058 repair: %w

Error message

deduplicating wisp_dependencies before the 0058 repair: %w

What it means

This error wraps a SQL failure raised while deduplicating wisp_dependencies rows during the 0058 forward-shape schema repair. Before unique keys (uk_*) can be added, rows that collide on the natural identity (issue_id + null-safe depends_on columns) must be deleted; if the DELETE fails the repair aborts so it never adds keys over duplicate data.

Source

Thrown at internal/storage/schema/wisp_dep_forward_repair.go:445

// wisp-target rows as distinct because their NULL issue targets never compare
// equal. MIN(id) is an arbitrary but deterministic survivor, which is the
// property that matters -- it makes a resumed run pick the same row.
func dedupeWispDepNaturalIdentity(ctx context.Context, db DBConn) error {
	if _, err := db.ExecContext(ctx, `
		DELETE wd FROM wisp_dependencies wd
		JOIN (
			SELECT MIN(id) AS keep_id, issue_id, depends_on_issue_id, depends_on_wisp_id, depends_on_external
			FROM wisp_dependencies
			GROUP BY issue_id, depends_on_issue_id, depends_on_wisp_id, depends_on_external
			HAVING COUNT(*) > 1
		) dup
		  ON wd.issue_id = dup.issue_id
		 AND wd.depends_on_issue_id <=> dup.depends_on_issue_id
		 AND wd.depends_on_wisp_id <=> dup.depends_on_wisp_id
		 AND wd.depends_on_external <=> dup.depends_on_external
		WHERE wd.id <> dup.keep_id
	`); err != nil {
		return fmt.Errorf("deduplicating wisp_dependencies before the 0058 repair: %w", err)
	}
	return nil
}

// ensureWispDepFinalKeysAndConstraints completes the final shape. Each object
// is added only if absent, so this finishes a partially-rebuilt table rather
// than failing on a duplicate key name -- and re-running it on a converged
// database does nothing at all.
func ensureWispDepFinalKeysAndConstraints(ctx context.Context, db DBConn) error {
	for _, k := range wispDepFinalKeys {
		present, err := schemaIndexExists(ctx, db, wispDepTable, k.name)
		if err != nil {
			return err
		}
		if present {
			continue
		}
		if _, err := db.ExecContext(ctx, "ALTER TABLE wisp_dependencies "+k.definition); err != nil {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Ensure ensureWispDepSurrogateKey ran first — verify the wisp_dependencies.id column and its PRIMARY KEY exist before dedupe
  2. Run the migration/repair as a database user with DELETE and ALTER privileges on wisp_dependencies
  3. Inspect the wrapped MySQL/Dolt error for the root cause (syntax, lock wait, unknown column) and fix that underlying issue
  4. Back up the database, then re-run the repair; it is idempotent and resumes partially-repaired tables

Example fix

// before (fails: id column missing on legacy table)
dbd upgrade  // dedupe fails with "Unknown column 'id'"
// after
// run the full repair path so ensureWispDepSurrogateKey adds id before dedupe,
// or manually: ALTER TABLE wisp_dependencies ADD COLUMN id CHAR(36) NOT NULL DEFAULT (UUID()) PRIMARY KEY FIRST;
Defensive patterns

Strategy: validation

Validate before calling

hasID, err := schemaColumnExists(ctx, db, "wisp_dependencies", "id")
if err != nil || !hasID {
    return errors.New("run surrogate-key step before dedupe")
}

Try / catch

if err := repairWispDependenciesForwardShape(ctx, db); err != nil {
    log.Printf("0058 repair dedupe failed, database unchanged: %v", err)
    return err
}

Prevention

When it happens

Trigger: Running the wisp_dependencies forward repair (repairWispDependenciesForwardShape) on a legacy-shaped store where the DELETE wd FROM wisp_dependencies wd JOIN (...) dup statement fails — e.g. missing id column (dedupe requires the surrogate id added by ensureWispDepSurrogateKey first), SQL syntax/permission errors, or a corrupted/locked table.

Common situations: Upgrading a pre-0058 beads database whose wisp_dependencies table still has the legacy composite primary key and accumulated duplicate rows; interrupted prior migrations leaving the table half-repaired; database user lacking DELETE/ALTER privileges.

Related errors


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