gastownhall/beads · error

commit: %w

Error message

commit: %w

What it means

After writing records, classic import commits the transaction via store.Commit; any commit error that is not the benign 'nothing to commit' no-op is surfaced as `commit: <cause>`. This is the final durability step of the import.

Source

Thrown at cmd/bd/import.go:360

		importResult, err := importIssuesCore(ctx, "", store, issues, opts)
		if err != nil {
			return fmt.Errorf("import failed: %w", err)
		}
		applyImportOutcome(&result, importResult)
	}

	if result.Created > 0 || result.Memories > 0 {
		commitMsg := fmt.Sprintf("bd import: %d issues", result.Created)
		if result.Memories > 0 {
			commitMsg += fmt.Sprintf(", %d memories", result.Memories)
		}
		commitMsg += fmt.Sprintf(" from %s", filepath.Base(source))
		if err := store.Commit(ctx, commitMsg); err != nil {
			// An import can be a working-set no-op: re-importing an
			// identical snapshot, or equal-timestamp rows whose guarded
			// upsert kept every local column (bd-hj85c).
			if !strings.Contains(err.Error(), "nothing to commit") {
				return fmt.Errorf("commit: %w", err)
			}
		}
	}

	// Sync issue_prefix from config.yaml to the database if stale (be-llaf).
	// store.Commit skips the config table (GH#2455), so we use CommitWithConfig
	// for this intentional config update after the issues commit completes.
	// config.yaml is authoritative here and existing issue IDs are intentionally
	// left unchanged: this deliberately bypasses the `bd config set issue_prefix`
	// guard for the import/migration flow and is not a rename.
	if yamlPrefix := config.GetString("issue-prefix"); yamlPrefix != "" {
		if dbPrefix, _ := store.GetConfig(ctx, "issue_prefix"); dbPrefix != yamlPrefix {
			if setErr := store.SetConfig(ctx, "issue_prefix", yamlPrefix); setErr == nil {
				_ = store.CommitWithConfig(ctx, "bd import: sync issue_prefix from config.yaml")
			}
		}
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped error after `commit:` for the storage-level cause
  2. Ensure no concurrent bd process is writing, then re-run the import
  3. Free disk space / restore write permissions on the database and its directory
  4. Run `bd doctor` and, if the repo uses remote sync, `bd dolt pull` before retrying

Example fix

// before
$ bd import data.jsonl
commit: database is locked
// after
$ bd doctor                       # confirm no locks
$ bd import data.jsonl            # retry import cleanly
Defensive patterns

Strategy: retry

Validate before calling

bd doctor   # no locks, writable DB, healthy driver
[ -w .beads/ ] || echo 'database dir not writable'

Try / catch

for i in 1 2 3; do
  bd import data.jsonl && break
  grep -q 'commit:' <(bd import data.jsonl 2>&1) && sleep $((i*i))
done

Prevention

When it happens

Trigger: `bd import` created/updated records but store.Commit failed: database locked by a concurrent process, storage driver error, disk full, or a non-'nothing to commit' failure inside the Dolt-backed commit.

Common situations: Another bd session mid-write during import; read-only database mount; insufficient disk space; driver-level commit aborts on large imports.

Related errors


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