gastownhall/beads · error
inspect dirty config before pull: %w
Error message
inspect dirty config before pull: %w
What it means
Before concluding a pull/merge, assertDirtyConfigUserKVOnly inspects dolt_diff('HEAD','WORKING','config') to ensure any dirty config rows are internal kv.* keys only (GH#2474). This error wraps a failure of the dolt_diff query itself, meaning the safety check could not run, so the merge is refused before staging. It is a protective abort, not corruption.
Source
Thrown at internal/storage/dolt/store.go:3185
// assertDirtyConfigUserKVOnly returns an error unless every config row dirty in
// the working set is this clone's own user KV data (the kv.* namespace, which
// includes kv.memory.* memories). The pre-pull auto-commit opts config into the
// staged set so user KV writes sync and stop wedging DOLT_MERGE (GH#2474), but
// auto-committing an unrelated dirty internal config key such as issue_prefix
// would re-open the GH#2455 stale-config corruption — that is the operator's
// explicit `bd dolt commit` to make, not the pull's. Screening on the whole kv.
// namespace (not just kv.memory.*) un-wedges generic `bd kv set` writes too: a
// kv.* row is this clone's own data, exactly as safe to auto-commit as a memory,
// and a genuine kv.* merge conflict is still left for the operator because
// auto-resolution stays kv.memory.*-only (configConflictsAreMemoryConvergent).
// config's primary key is `key`, so dolt_diff exposes to_key/from_key; an add or
// delete leaves one side NULL, so COALESCE picks whichever key the change carries.
func (s *DoltStore) assertDirtyConfigUserKVOnly(ctx context.Context, conn *sql.Conn) error {
rows, err := conn.QueryContext(ctx,
"SELECT COALESCE(to_key, from_key) FROM dolt_diff('HEAD', 'WORKING', 'config')")
if err != nil {
return fmt.Errorf("inspect dirty config before pull: %w", err)
}
defer rows.Close()
var unsafe []string
for rows.Next() {
var key sql.NullString
if err := rows.Scan(&key); err != nil {
return fmt.Errorf("scan dirty config key: %w", err)
}
if key.Valid && !strings.HasPrefix(key.String, kvkeys.Prefix) {
unsafe = append(unsafe, key.String)
}
}
if err := rows.Err(); err != nil {
return fmt.Errorf("iterate dirty config diff: %w", err)
}
if len(unsafe) > 0 {
return fmt.Errorf("refusing to auto-commit %d dirty internal config key(s) before pull: %s; "+View on GitHub (pinned to 71377f2769)
Solutions
- Check the wrapped error; retry the pull on a fresh pinned connection if transient.
- Verify the Dolt engine version supports dolt_diff('HEAD','WORKING',table) table-function syntax; upgrade if not.
- Inspect merge state (dolt_merge_status) — an open or broken merge can invalidate WORKING diffing; resolve or abort the merge first.
- Manually run SELECT ... FROM dolt_diff('HEAD','WORKING','config') in a SQL shell to reproduce and see the server-side message.
Defensive patterns
Strategy: retry
Validate before calling
// precheck: engine supports the table-function form and clean merge state
_, err := conn.QueryContext(ctx, "SELECT 1 FROM dolt_diff('HEAD', 'WORKING', 'config') LIMIT 1")
if err != nil { /* resolve engine version / merge state before pull */ } Try / catch
err := store.Pull(ctx, ...)
if err != nil && strings.Contains(err.Error(), "inspect dirty config before pull") {
// check dolt_merge_status, resolve open merge, retry pull
} Prevention
- Conclude or abort open merges before pulling (dolt_merge_status).
- Keep the Dolt engine version supporting dolt_diff('HEAD','WORKING',table).
- Keep internal config keys under the kv.* prefix so the safety check can pass.
- Retry pulls on a fresh connection after transient SQL errors.
When it happens
Trigger: The QueryContext on dolt_diff fails: Dolt version lacking the dolt_diff table-function form used here, invalid arguments (bad 'HEAD'/'WORKING' refs or table name), session error on the pinned connection, or transient driver failure.
Common situations: Older Dolt engines with a different dolt_diff signature; a pull attempted while the working set/HEAD ref is in an unexpected state (mid-merge, detached session); network blip to a remote server.
Related errors
- database config fix not applicable for Dolt backend (data is
- failed to set routing mode: %w
- failed to set routing contributor path: %w
- failed to set sync remote: %w
- failed to set routing.mode: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/70e8ee57d495dd6d.
Report an issue: GitHub.