gastownhall/beads · error

failed to walk directory tree: %w

Error message

failed to walk directory tree: %w

What it means

ClassicArtifacts cleans up classic-beads artifact files (SQLite WAL/SHM files, backup DBs, JSONL cruft, etc.) by walking the beads directory tree with filepath.Walk. If the Walk callback returns a non-nil, non-SkipDir error, the walk aborts and this error wraps it. The cleanup summary is not printed/complete because the traversal itself failed.

Source

Thrown at cmd/bd/doctor/fix/artifacts.go:43

		base := filepath.Base(walkPath)
		if info.IsDir() && (base == "node_modules" || base == "vendor" || base == "__pycache__") {
			return filepath.SkipDir
		}

		// We only care about directories named ".beads"
		if !info.IsDir() || base != ".beads" {
			return nil
		}

		r, s, e := cleanBeadsDirArtifacts(walkPath)
		removed += r
		skipped += s
		errCount += e

		return filepath.SkipDir
	})
	if err != nil {
		return fmt.Errorf("failed to walk directory tree: %w", err)
	}

	// Report summary
	fmt.Printf("  Artifact cleanup: %d removed, %d skipped, %d errors\n", removed, skipped, errCount)

	if skipped > 0 {
		fmt.Println("  Skipped items may need manual review (e.g., issues.jsonl in dolt dirs, beads.db files)")
	}

	if errCount > 0 {
		return fmt.Errorf("%d artifact(s) could not be removed", errCount)
	}

	return nil
}

// cleanBeadsDirArtifacts cleans artifacts from a single .beads directory.
// Returns counts of removed, skipped, and errored items.

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped %w error: if it's a PathError 'no such file or directory', verify the beads directory path exists before invoking cleanup.
  2. Fix filesystem permissions (chmod/chown) on the beads directory so the process can read and traverse it.
  3. If caused by a walk callback returning an unexpected error, audit the callback so only filepath.SkipDir is returned intentionally and other per-file errors are counted in errCount rather than aborting the walk.

Example fix

// before
return fmt.Errorf("read dir: %w", err) // aborts entire walk
// after
errCount++
return nil // record and continue walking
// and check root exists before walking:
if _, err := os.Stat(root); os.IsNotExist(err) { return nil }
Defensive patterns

Strategy: validation

Validate before calling

if info, err := os.Stat(beadsDir); err != nil || !info.IsDir() {
    return fmt.Errorf("beads directory %s missing or not a directory", beadsDir)
}

Try / catch

if err := artifacts.ClassicArtifacts(beadsDir); err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {
        // fix permissions or skip cleanup
    }
    return err
}

Prevention

When it happens

Trigger: Running the doctor artifacts fix (invoked by the listed tests or the bd doctor fix path) when filepath.Walk fails on the root directory: root path does not exist, permission denied reading a directory, symlink loops, or a custom walk callback error other than the intended SkipDir.

Common situations: Beads directory deleted mid-run; directory mounted read-only or with restrictive permissions; running as a user without read access to .beads; root path typo so the walk root is missing (PathError).

Related errors


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