crowdsecurity/crowdsec · error
unable to copy '%s' to '%s': %w
Error message
unable to copy '%s' to '%s': %w
What it means
After computing the destination inside the runtime hub, installPostoverflowItem copies the item file with Copy(). If the copy fails (source unreadable, destination not writable, missing directories), the error is wrapped naming both source and destination paths. This blocks the postoverflow from being installed for the hub test.
Source
Thrown at pkg/hubtest/postoverflow.go:33
return fmt.Errorf("can't get absolute path of '%s': %w", sourcePath, err)
}
sourceFilename := filepath.Base(sourcePath)
// runtime/hub/postoverflows/s00-enrich/crowdsecurity/
hubDirPostoverflowDest := filepath.Join(t.RuntimeHubPath, filepath.Dir(item.RemotePath))
// runtime/postoverflows/s00-enrich
itemTypeDirDest := fmt.Sprintf("%s/postoverflows/%s/", t.RuntimePath, item.Stage)
if err := createDirs([]string{hubDirPostoverflowDest, itemTypeDirDest}); err != nil {
return err
}
// runtime/hub/postoverflows/s00-enrich/crowdsecurity/rdns.yaml
hubDirPostoverflowPath := filepath.Join(hubDirPostoverflowDest, sourceFilename)
if err := Copy(sourcePath, hubDirPostoverflowPath); err != nil {
return fmt.Errorf("unable to copy '%s' to '%s': %w", sourcePath, hubDirPostoverflowPath, err)
}
// runtime/postoverflows/s00-enrich/rdns.yaml
postoverflowDirParserPath := filepath.Join(itemTypeDirDest, sourceFilename)
if err := os.Symlink(hubDirPostoverflowPath, postoverflowDirParserPath); err != nil {
if !os.IsExist(err) {
return fmt.Errorf("unable to symlink postoverflow '%s' to '%s': %w", hubDirPostoverflowPath, postoverflowDirParserPath, err)
}
}
return nil
}
func (t *HubTestItem) installPostoverflowCustomFrom(postoverflow string, customPath string) (bool, error) {
// we check if its a custom postoverflow
customPostOverflowPath := filepath.Join(customPath, postoverflow)
if _, err := os.Stat(customPostOverflowPath); os.IsNotExist(err) {
return false, nilView on GitHub (pinned to 909b515798)
Solutions
- Check the wrapped Copy error for the exact OS-level cause (ENOENT/EACCES)
- Ensure the runtime hub postoverflow directory exists and is writable
- Verify the source item file exists at t.HubPath/<RemotePath>
- Re-run `cscli hub update` if hub files are missing/corrupt
Defensive patterns
Strategy: try-catch
Validate before calling
src := filepath.Join(t.HubPath, item.RemotePath)
if _, err := os.Stat(src); err != nil {
return fmt.Errorf("source missing: %w", err)
}
if err := os.MkdirAll(filepath.Dir(dst), 0o755); err != nil {
return fmt.Errorf("dest dir: %w", err)
} Try / catch
if err := t.installPostoverflow(item); err != nil {
var perr *os.PathError
if errors.As(errors.Unwrap(err), &perr) {
log.Errorf("fs failure on %s: %v", perr.Path, perr.Err)
}
return err
} Prevention
- Ensure the runtime hub directories are created before install
- Keep the test runtime tree writable by the test user
- Don't mutate the hub tree while tests run
When it happens
Trigger: Copy(sourcePath, hubDirPostoverflowPath) fails: source file missing, target directory absent (hub dir creation failed earlier), or permission issues.
Common situations: Runtime hub directory not created due to earlier mkdir failure; read-only test runtime tree; hub item deleted between enumeration and install; disk full.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- unable to copy custom parser '%s' to '%s': %w
- cannot copy a folder onto itself
- while find parser asserts: %w
- while reading %s: %w
- while find scenario asserts: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/502e8dad19e59ac7.
Report an issue: GitHub.