gastownhall/beads · error

delete %s orphans: %w

Error message

delete %s orphans: %w

What it means

relinkSeveredCloneLocalFKs deletes orphaned rows that would violate the FK before re-adding the constraint. If the generated DELETE fails, this error wraps it and aborts the relink, leaving the constraint absent and orphans in place.

Source

Thrown at cmd/bd/doctor/fix/clone_local_fks.go:156

	severed, err := scanSeveredCloneLocalFKs(db)
	if err != nil {
		return err
	}
	if len(severed) == 0 {
		fmt.Println("  ✓ All clone-local FKs present")
		return nil
	}

	for _, fk := range severed {
		if fk.Orphans > 0 {
			//nolint:gosec // G201: identifiers come from the fixed CloneLocalFKs spec, not user input.
			deleteOrphans := fmt.Sprintf(
				`DELETE FROM %s WHERE %s IS NOT NULL AND NOT EXISTS (SELECT 1 FROM %s r WHERE r.%s = %s.%s)`,
				fk.Table, fk.Column, fk.RefTable, fk.RefColumn, fk.Table, fk.Column,
			)
			result, err := db.Exec(deleteOrphans)
			if err != nil {
				return fmt.Errorf("delete %s orphans: %w", fk.Table, err)
			}
			if verbose {
				removed, _ := result.RowsAffected()
				fmt.Printf("  Removed %d orphaned row(s) from %s\n", removed, fk.Table)
			}
		}

		//nolint:gosec // G201: identifiers come from the fixed CloneLocalFKs spec, not user input.
		addConstraint := fmt.Sprintf(
			`ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s) ON DELETE CASCADE ON UPDATE CASCADE`,
			fk.Table, fk.Constraint, fk.Column, fk.RefTable, fk.RefColumn,
		)
		if _, err := db.Exec(addConstraint); err != nil {
			return fmt.Errorf("re-add %s.%s: %w", fk.Table, fk.Constraint, err)
		}
		fmt.Printf("  ✓ Re-linked %s.%s (%d orphaned row(s) removed)\n", fk.Table, fk.Constraint, fk.Orphans)
	}
	return nil

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check the wrapped driver error for permission/lock problems; ensure the workspace is writable and no other bd process is running.
  2. Re-run `bd doctor` (fix mode) once write access is restored — the delete is idempotent per scan.
  3. If other FKs block deletion, resolve those constraints first (run the scan again to see all severed FKs).
  4. Restore the .beads Dolt store from backup if the write failure indicates corruption.
Defensive patterns

Strategy: validation

Validate before calling

// Ensure writable DB and no competing writers before relink:
if err := db.Ping(); err != nil { return err }
// verify write access
if _, err := db.Exec(`SELECT 1 FOR UPDATE`); err != nil { /* lock/perm check failed */ }

Try / catch

if err := CloneLocalFKEnforcement(ctx, db, verbose); err != nil && strings.Contains(err.Error(), "delete") {
	// orphan delete failed: check permissions/locks, then re-run fix
	return err
}

Prevention

When it happens

Trigger: The dynamic DELETE of orphan rows fails in relinkSeveredCloneLocalFKs (cmd/bd/doctor/fix/clone_local_fks.go:156) during CloneLocalFKEnforcement — write permission denied, storage locked, or ON DELETE CASCADE side effects rejected by the engine.

Common situations: Read-only database or filesystem permissions on .beads, a concurrent bd process holding Dolt write locks, or FK validation errors from other constraints on the rows being deleted.

Related errors


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