gastownhall/beads · error

check rename collision in %s: %w

Error message

check rename collision in %s: %w

What it means

Wrapped SQL failure from checkRenameTargetCollision: the probe that checks whether renaming a dependency target to newID would conflict with another target column on the same issue_id failed at the driver level. Unlike the deliberate collision error (3545), the query itself errored rather than finding a row. Table-not-exist is tolerated as no-op.

Source

Thrown at internal/storage/issueops/dependencies.go:898

	query := fmt.Sprintf(`
		SELECT 1 FROM %s a
		JOIN %s b ON a.issue_id = b.issue_id
		WHERE a.%s = ?
		  AND (b.%s = ? OR b.%s = ?)
		LIMIT 1
	`, table, table, typedCol, otherCols[0], otherCols[1])

	var found int
	err := tx.QueryRowContext(ctx, query, newID, newID, newID).Scan(&found)
	if err == sql.ErrNoRows {
		return nil
	}
	if err != nil {
		if isTableNotExistError(err) {
			return nil
		}
		return fmt.Errorf("check rename collision in %s: %w", table, err)
	}
	return fmt.Errorf("rename to %s collides with existing dependency target in %s", newID, table)
}

// RemoveDependencyInTx removes a dependency between two issues within an
// existing transaction. Automatically routes to wisp_dependencies if the
// source issue is an active wisp. When emitEvent is set and a row is actually
// removed it records a dependency_removed event (attributed to actor) on the
// source's event table; a no-op remove of a missing edge, or a structural remove
// with emitEvent unset, records nothing. Only the explicit bd dep remove verb
// sets emitEvent; structural removals (issue delete, reparent, batch, duplicate
// cleanup) leave it unset so they wire edges away silently, mirroring the
// proxied repository's DepInsertOpts.EmitEvent gate so both backends record
// identical history.
//
// It returns whether a dependency_removed event was actually written, so callers
// that stage tables for a Dolt commit stage the events table only when an event
// row exists (avoiding the sweep-unrelated-rows hazard doltAddAndCommit guards

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped driver error; retry the rename transaction if it is transient (connection, timeout, lock).
  2. Verify schema completeness with migrations; both dependency tables need depends_on_issue_id, depends_on_wisp_id, depends_on_external.
  3. Confirm the DB user can SELECT from both dependency tables.
  4. Check server logs (Dolt/SQLite) for the underlying query failure.

Example fix

// before: rename fails on flaky connection
err := store.RenameIssue(ctx, oldID, newID)
// after: retry rename with backoff on transient DB errors
err = withRetry(3, func() error { return store.RenameIssue(ctx, oldID, newID) })
Defensive patterns

Strategy: retry

Validate before calling

// verify rename-probe prerequisites: table readable and expected columns present
for _, c := range []string{"depends_on_issue_id", "depends_on_wisp_id", "depends_on_external"} {
    if err := db.QueryRow("SELECT " + c + " FROM dependencies LIMIT 1").Err(); err != nil {
        return fmt.Errorf("dependencies.%s unavailable; migrate first: %w", c, err)
    }
}

Type guard

func isRenameProbeFailure(err error) bool {
    return err != nil && strings.Contains(err.Error(), "check rename collision")
}

Try / catch

err := store.RenameIssue(ctx, oldID, newID)
if isRenameProbeFailure(err) && isTransient(errors.Unwrap(err)) {
    err = withBackoff(3, func() error { return store.RenameIssue(ctx, oldID, newID) })
}

Prevention

When it happens

Trigger: Any caller (replaceDependencyTargetInTx, RetargetInboundDependenciesToWispInTx, RetargetInboundDependenciesToIssueInTx, UpdateIssueIDInDependencyTargetsInTx) runs the JOIN probe against dependencies or wisp_dependencies and gets a non-ErrNoRows driver error — connectivity loss, timeout, schema corruption, permission denial.

Common situations: Renaming an issue ID (bd mv / update --id) while the DB connection is flaky; Dolt server restart mid-rename; insufficient SELECT grants; a partially migrated schema missing typed target columns.

Related errors


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