gastownhall/beads · error
scanning artifacts at %s: %w
Error message
scanning artifacts at %s: %w
What it means
ScanForArtifacts wraps errors returned by filepath.WalkDir while scanning the repository tree for leftover SQLite artifacts, cruft .beads directories, and redirect issues. It reports that the filesystem walk itself failed (not an individual file finding).
Source
Thrown at cmd/bd/doctor/artifacts.go:129
// Skip node_modules and similar
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
}
// Found a .beads directory - scan it
scanBeadsDir(path, &report)
// Don't descend into .beads/ itself (we've scanned it)
return filepath.SkipDir
})
if walkErr != nil {
return report, fmt.Errorf("scanning artifacts at %s: %w", rootPath, walkErr)
}
report.TotalCount = len(report.SQLiteArtifacts) +
len(report.CruftBeadsDirs) + len(report.RedirectIssues)
for _, findings := range [][]ArtifactFinding{
report.SQLiteArtifacts,
report.CruftBeadsDirs, report.RedirectIssues,
} {
for _, f := range findings {
if f.SafeDelete {
report.SafeDeleteCount++
}
}
}
return report, nil
}View on GitHub (pinned to 71377f2769)
Solutions
- Fix permissions on unreadable directories reported in the wrapped error (chmod/chown or run with adequate privileges)
- Remove or repair broken symlinks in the tree being scanned
- Exclude exotic mounts from the scan by running bd doctor inside the project directory rather than above it
- Retry after fixing; then re-run `bd doctor` to confirm the artifact scan completes
Example fix
// before chmod 000 ./node_modules/.cache/locked-dir // after chmod u+rX ./node_modules/.cache/locked-dir
Defensive patterns
Strategy: retry
Validate before calling
import "os"
func canWalk(root string) error {
return filepath.WalkDir(root, func(p string, d os.DirEntry, err error) error {
if err != nil { return err }
if d.IsDir() {
if f, ferr := os.Open(p); ferr != nil { return ferr } else { f.Close() }
}
return nil
})
} Try / catch
report, err := ScanForArtifacts(root)
if err != nil {
var pe *fs.PathError
if errors.As(err, &pe) {
log.Printf("scan blocked at %s: %v — fix perms and retry", pe.Path, pe.Err)
}
return err
} Prevention
- Keep repository directories world-readable for CI/agent users
- Remove broken symlinks before running doctor scans
- Run scans on local filesystems, not flaky network mounts
- Note SkipDir is used internally; never return arbitrary walk errors from custom walkers
When it happens
Trigger: ScanForArtifacts (via CheckClassicArtifacts during `bd doctor`) when filepath.WalkDir returns a non-SkipDir error — e.g. unreadable directories, permission-denied on a subtree, symlink loops, or deleted dirs mid-walk — at cmd/bd/doctor/artifacts.go:129.
Common situations: Scanning a repo containing root-owned or permission-restricted directories, a broken/looping symlink, or a network mount that drops out during the walk; also from tests that feed ScanForArtifacts odd fixture trees.
Related errors
- failed to create output file: %w
- unable to read plugin file: %w
- failed to walk directory tree: %w
- invalid path: %w
- creating .bd-dolt-ok marker: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/69266ae1cfb291ec.
Report an issue: GitHub.