gastownhall/beads · critical

dolt add %s after SQL mutation: %w: %w

Error message

dolt add %s after SQL mutation: %w: %w

What it means

CALL DOLT_ADD failed for a table after a SQL mutation. Wrapped with ErrCommitIndeterminate because the data mutation succeeded but staging/publication did not, leaving the commit outcome ambiguous.

Source

Thrown at internal/storage/dolt/store.go:3298

func (s *DoltStore) doltAddAndCommit(ctx context.Context, tables []string, commitMsg string) error {
	// Batch/off auto-commit (bd-4wamg): leave the writes in the working set
	// for a later explicit commit point (bd dolt commit / CommitPending),
	// matching doltAddAndCommitInTx.
	if issueops.VersionCommitDeferred(ctx) {
		return nil
	}
	return s.withCircuitWrite(ctx, func(ctx context.Context) error {
		conn, err := s.db.Conn(ctx)
		if err != nil {
			return s.recordDoltPublicationFailure(ctx,
				fmt.Errorf("acquire connection after SQL mutation: %w: %w", err, ErrCommitIndeterminate))
		}
		defer conn.Close()

		for _, table := range tables {
			if err := schema.DrainCall(ctx, conn, "CALL DOLT_ADD(?)", table); err != nil {
				return s.recordDoltPublicationFailure(ctx,
					fmt.Errorf("dolt add %s after SQL mutation: %w: %w", table, err, ErrCommitIndeterminate))
			}
		}

		// Skip the commit when nothing was actually staged (idempotent no-op
		// write), so Dolt does not log a server-side "nothing to commit" warning
		// on every reconcile-cadence call. The guard tests the STAGED set rather
		// than the whole working set because this helper stages only a fixed
		// table list — an unrelated dirty table must not trigger an empty '-m'
		// commit. A guard-read failure is NOT a publication failure: nothing has
		// been committed and nothing is indeterminate, so plain error return.
		staged, err := issueops.HasStagedChanges(ctx, conn)
		if err != nil {
			return fmt.Errorf("check staged changes before commit: %w", err)
		}
		if !staged {
			return nil
		}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Check `bd dolt status` to see whether some/all tables were staged and whether the commit landed; do not blind-retry an indeterminate write.
  2. Restore server connectivity and re-run; staging is idempotent.
  3. If the table is missing, verify schema version consistency between bd and the database (bd doctor).
  4. Check for locks from other bd processes and wait/retry.
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm all target tables exist before the mutation/commit sequence
for _, t := range tables {
    if !tableExists(ctx, conn, t) {
        return fmt.Errorf("table %s missing; run `bd doctor`", t)
    }
}

Try / catch

if errors.Is(err, ErrCommitIndeterminate) && strings.Contains(err.Error(), "dolt add") {
    // inspect dolt status for staged tables, then resume publication
}

Prevention

When it happens

Trigger: commitWorkingSetAfterSQLCommit iterates the table list and DOLT_ADD fails — server unreachable, table locked, or the table name is not a valid Dolt table after a rename/schema change.

Common situations: Dolt server restart mid-operation; schema drift after a bd version upgrade left a listed table missing; lock contention with another writer.

Related errors


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