gastownhall/beads · error
dolt clone failed: %w Output: %s Could not inspect failed cl
Error message
dolt clone failed: %w Output: %s Could not inspect failed clone target %q before cleanup: %v On Windows this usually means a dolt or bd process, or antivirus scanner, still has a file handle open under `.dolt/noms/LOCK`. Stop stuck dolt/bd processes, wait a moment, delete the directory manually if it remains, then retry `bd bootstrap`
What it means
This branch of formatFailedCloneTargetError fires when `dolt clone` failed AND cleanup of the partial clone target could not even be inspected: os.Lstat of the target's .dolt returned a non-NotExist error. The message is Windows-centric — it almost always means another process (dolt, bd, or an antivirus scanner) still holds a handle under .dolt/noms/LOCK, so the partial clone is left in place with remediation instructions.
Source
Thrown at internal/storage/dolt/bootstrap.go:142
if err == nil || os.IsNotExist(err) {
return true, nil
}
if attempt >= len(failedCloneCleanupRetryDelays) {
return true, err
}
time.Sleep(failedCloneCleanupRetryDelays[attempt])
}
}
func formatFailedCloneTargetError(cloneErr error, output []byte, cloneTarget string, cleaned bool, cleanupErr error) error {
if cleanupErr == nil && cleaned {
return fmt.Errorf("dolt clone failed: %w\nOutput: %s\nCleaned up failed clone target %q; fix the clone error above and retry `bd bootstrap`", cloneErr, output, cloneTarget)
}
if cleanupErr == nil {
return fmt.Errorf("dolt clone failed: %w\nOutput: %s", cloneErr, output)
}
if !cleaned {
return fmt.Errorf("dolt clone failed: %w\nOutput: %s\nCould not inspect failed clone target %q before cleanup: %v\nOn Windows this usually means a dolt or bd process, or antivirus scanner, still has a file handle open under `.dolt/noms/LOCK`. Stop stuck dolt/bd processes, wait a moment, delete the directory manually if it remains, then retry `bd bootstrap`", cloneErr, output, cloneTarget, cleanupErr)
}
return fmt.Errorf("dolt clone failed: %w\nOutput: %s\nCould not clean up failed clone target %q after retrying: %v\nOn Windows this usually means a dolt or bd process, or antivirus scanner, still has a file handle open under `.dolt/noms/LOCK`. Stop stuck dolt/bd processes, wait a moment, delete the directory manually if it remains, then retry `bd bootstrap`", cloneErr, output, cloneTarget, cleanupErr)
}
func doltCloneArgs(remoteURL, target string) []string {
args := []string{"clone"}
if user := os.Getenv("DOLT_REMOTE_USER"); user != "" {
args = append(args, "--user", user)
}
return append(args, remoteURL, target)
}
// BootstrapFromGitRemoteWithDB is deprecated. Use BootstrapFromRemoteWithDB instead.
func BootstrapFromGitRemoteWithDB(ctx context.Context, doltDir, gitRemoteURL, database string) (bool, error) {
return BootstrapFromRemoteWithDB(ctx, doltDir, gitRemoteURL, database)
}
// pathExists reports whether path exists (of any type), without followingView on GitHub (pinned to 71377f2769)
Solutions
- Wait a few seconds and retry `bd bootstrap` — the error text's cleanup retry loop (50ms–500ms) may simply need longer for the lock to release.
- Kill any stuck dolt/bd processes (Task Manager or `taskkill /F /IM dolt.exe`) that still hold handles under the target directory.
- Add an antivirus/Defender exclusion for the workspace's .beads directory so the scanner stops locking .dolt/noms/LOCK.
- If the partial directory remains, delete it manually (`rm -rf .beads/dolt/<db>` or Explorer) once handles are released, then retry.
- Move the workspace off network-synced storage (OneDrive/Dropbox/SMB share) to a local disk if locking recurs.
Example fix
# before (Windows): clone failed, LOCK held $ bd bootstrap # Could not inspect failed clone target ... .dolt/noms/LOCK # after: release the handle, clean up, retry $ taskkill /F /IM dolt.exe $ rmdir /s /q .beads\dolt\beads $ bd bootstrap
Defensive patterns
Strategy: retry
Try / catch
if err != nil && strings.Contains(err.Error(), "Could not inspect failed clone target") {
time.Sleep(2 * time.Second) // let AV/scanner release .dolt/noms/LOCK
// retry bootstrap or clean up manually
} Prevention
- Add antivirus exclusions for the workspace .beads directory (Windows/Defender).
- Keep the repo on a local disk, not OneDrive/Dropbox/SMB-synced storage.
- Ensure no long-running dolsql/dolt process holds the database directory during bootstrap.
- Retry after a short delay — the library's built-in retries (up to ~900ms) may not outlast the lock.
When it happens
Trigger: `dolt clone` fails, then removeFailedCloneTargetWithRetry's os.Lstat(<target>/.dolt) errors with something other than NotExist (permission denied, sharing violation, I/O error) — classic Windows file-locking on .dolt/noms/LOCK right after a failed dolt process exits.
Common situations: Windows machines where Defender or another AV scans the freshly written .dolt files immediately after a failed clone; a lingering dolsql/dolt process holding the noms LOCK; OneDrive/Dropbox sync locking .beads paths; the repo living on a network share with handle delays.
Related errors
- dolt clone failed: %w Output: %s Could not clean up failed c
- dolt clone failed: %w Output: %s Clone target %q already exi
- dolt clone failed: %w Output: %s Cleaned up failed clone tar
- dolt clone failed: %w Output: %s
- lock already held by another process
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/7640f8acb4f93637.
Report an issue: GitHub.