gastownhall/beads · error
checking sidecar %s: %w
Error message
checking sidecar %s: %w
What it means
This wraps an os.Stat failure on the retire op's source sidecar during retirement. pathExists distinguishes only 'exists' vs os.ErrNotExist; any other stat error (permission, I/O) surfaces here. The retire step aborts mid-apply, so earlier operations may already have been applied.
Source
Thrown at cmd/bd/migrate_hooks_apply.go:385
if err != nil {
return fmt.Errorf("comparing sidecars %s and %s: %w", op.SourcePath, op.DestinationPath, err)
}
if !equal {
return fmt.Errorf(
"artifact collision for %s: %s already exists with different content",
op.SourcePath,
op.DestinationPath,
)
}
}
return nil
}
func retireHookSidecar(op hookMigrationRetireOp) (string, error) {
sourceExists, err := pathExists(op.SourcePath)
if err != nil {
return "", fmt.Errorf("checking sidecar %s: %w", op.SourcePath, err)
}
if !sourceExists {
return "", nil
}
destinationExists, err := pathExists(op.DestinationPath)
if err != nil {
return "", fmt.Errorf("checking sidecar destination %s: %w", op.DestinationPath, err)
}
if destinationExists {
equal, err := filesEqual(op.SourcePath, op.DestinationPath)
if err != nil {
return "", fmt.Errorf("comparing sidecar %s to %s: %w", op.SourcePath, op.DestinationPath, err)
}
if !equal {
return "", fmt.Errorf("artifact collision for %s: %s already exists with different content", op.SourcePath, op.DestinationPath)
}View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped error and stat the source path manually to identify the failing component.
- Restore access to the source directory (chown/chmod or remount).
- Re-run the migration once access is restored — already-completed retire ops are idempotent (missing sources are skipped).
Example fix
// before $ ls -ld /path/to/source-dir perms: root-only // after $ sudo chmod a+rx /path/to/source-dir $ bd migrate
Defensive patterns
Strategy: validation
Validate before calling
if _, err := os.Stat(filepath.Dir(op.SourcePath)); err != nil {
return fmt.Errorf("source dir not accessible: %w", err)
} Try / catch
if _, err := retireHookSidecar(op); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, os.ErrPermission) {
// surface a permission-fix hint
}
return err
} Prevention
- Run bd as a user with write access to the repo's hook directories
- Keep source sidecar files on a reliably mounted local filesystem
- Re-run migrate after fixing access; retire ops are idempotent
When it happens
Trigger: During `bd migrate` apply, os.Stat(op.SourcePath) fails with an error other than os.ErrNotExist — e.g. the source sidecar's parent directory became inaccessible, or the path sits on a failed mount.
Common situations: Permissions on the source directory changed after validation passed; an NFS/removable mount dropped mid-run; security software blocked the stat.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- checking destination sidecar %s: %w
- checking sidecar destination %s: %w
- removing already-retired sidecar %s: %w
- dolt path is not executable
- failed to create backup directory: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/a16d3c2b62211663.
Report an issue: GitHub.