sipeed/picoclaw · error
close destination file %s: %w
Error message
close destination file %s: %w
What it means
Raised by copyDirectory (used by builtin skill installation) while walking the source tree: io.Copy to the destination file succeeded, but the subsequent dstFile.Close() failed. Closing a written file is where buffered data is flushed and final metadata committed, so a close failure usually means the copy is actually incomplete even though io.Copy reported no error.
Source
Thrown at cmd/picoclaw/internal/skills/helpers.go:356
if info.IsDir() {
return os.MkdirAll(dstPath, info.Mode())
}
srcFile, err := os.Open(path)
if err != nil {
return err
}
defer srcFile.Close()
dstFile, err := os.OpenFile(dstPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, info.Mode())
if err != nil {
return err
}
_, copyErr := io.Copy(dstFile, srcFile)
if closeErr := dstFile.Close(); closeErr != nil && copyErr == nil {
return fmt.Errorf("close destination file %s: %w", dstPath, closeErr)
}
return copyErr
})
}
View on GitHub (pinned to 49183d7e8d)
Solutions
- Check the wrapped errno: ENOSPC -> free disk space; EIO -> inspect device/dmesg; EACCES -> fix permissions on destination
- Exclude the workspace skills directory from sync/antivirus real-time scanning and retry the install
- Verify destination filesystem health (remount, fsck) if EIO repeats
- Retry the builtin install after remediation; partially copied dirs are truncated by O_TRUNC on rerun
Defensive patterns
Strategy: fallback
Validate before calling
func diskAvailable(path string, need uint64) bool {
var st syscall.Statfs_t
if err := syscall.Statfs(path, &st); err != nil { return false }
return uint64(st.Bavail)*uint64(st.Bsize) > need
} Try / catch
err := copyDirectory(src, dst)
if err != nil {
var pathErr *os.PathError
if errors.As(err, &pathErr) && pathErr.Op == "close" {
// treat copy as incomplete: remove partial dst and retry or report low-disk
}
} Prevention
- Check free disk space before installing builtin skills
- Exclude workspace skills dirs from sync clients and real-time antivirus scans
- Treat any close error as a failed copy: clean up partial destinations
When it happens
Trigger: Disk fills up exactly at flush time (ENOSPC on close), I/O error on the destination device, or an external program (antivirus, sync client) truncating/locking the destination between write and close. Occurs during `picoclaw skills install --builtin`-style copying of ./picoclaw/skills/<name> into the workspace.
Common situations: Small or nearly-full disk on the workspace volume; workspace inside a cloud-sync folder where the sync engine interferes; flaky USB/network mount; destination on a filesystem enforcing quotas.
Related errors
- write temp file: %w
- close temp file: %w
- write result: %w
- skill '%s' not found
- failed to remove skill '%s': %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/e137f0e70b25e1d7.
Report an issue: GitHub.