crowdsecurity/crowdsec · error
unable to copy '%s' to '%s': %w
Error message
unable to copy '%s' to '%s': %w
What it means
installScenarioItem copies the scenario file from the hub directory (RuntimeHubPath) into the test's runtime hub scenarios directory. If the file copy fails (Copy wraps os-level create/read/copy errors), this error reports both source and destination paths plus the underlying cause. Typical causes are missing directories, permission problems, or the source file not existing.
Source
Thrown at pkg/hubtest/scenario.go:32
return fmt.Errorf("can't get absolute path of '%s': %w", sourcePath, err)
}
sourceFilename := filepath.Base(sourcePath)
// runtime/hub/scenarios/crowdsecurity/
hubDirScenarioDest := filepath.Join(t.RuntimeHubPath, filepath.Dir(item.RemotePath))
// runtime/parsers/scenarios/
itemTypeDirDest := fmt.Sprintf("%s/scenarios/", t.RuntimePath)
if err := createDirs([]string{hubDirScenarioDest, itemTypeDirDest}); err != nil {
return err
}
// runtime/hub/scenarios/crowdsecurity/ssh-bf.yaml
hubDirScenarioPath := filepath.Join(hubDirScenarioDest, sourceFilename)
if err := Copy(sourcePath, hubDirScenarioPath); err != nil {
return fmt.Errorf("unable to copy '%s' to '%s': %w", sourcePath, hubDirScenarioPath, err)
}
// runtime/scenarios/ssh-bf.yaml
scenarioDirParserPath := filepath.Join(itemTypeDirDest, sourceFilename)
if err := os.Symlink(hubDirScenarioPath, scenarioDirParserPath); err != nil {
if !os.IsExist(err) {
return fmt.Errorf("unable to symlink scenario '%s' to '%s': %w", hubDirScenarioPath, scenarioDirParserPath, err)
}
}
return nil
}
func (t *HubTestItem) installScenarioCustomFrom(scenario string, customPath string) (bool, error) {
// we check if its a custom scenario
customScenarioPath := filepath.Join(customPath, scenario)
if _, err := os.Stat(customScenarioPath); os.IsNotExist(err) {
return false, nilView on GitHub (pinned to 909b515798)
Solutions
- Check the wrapped error to identify whether the source is missing or the destination is unwritable.
- Re-download the hub: 'cscli hub update' then re-run the test.
- Fix permissions/ownership on the runtime hub directory (or run as the right user).
- Ensure the parent destination directory exists before Copy (MkdirAll was done earlier; verify it succeeded).
Example fix
// before
if err := Copy(sourcePath, hubDirScenarioPath); err != nil {
return fmt.Errorf("unable to copy '%s' to '%s': %w", sourcePath, hubDirScenarioPath, err)
}
// after
if err := os.MkdirAll(filepath.Dir(hubDirScenarioPath), os.ModePerm); err != nil {
return err
}
if err := Copy(sourcePath, hubDirScenarioPath); err != nil {
return fmt.Errorf("unable to copy '%s' to '%s': %w", sourcePath, hubDirScenarioPath, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := os.Stat(sourcePath); err != nil {
return fmt.Errorf("hub scenario missing: %w", err)
} Try / catch
if err := Copy(sourcePath, dest); err != nil {
var perr *os.PathError
if errors.As(err, &perr) && os.IsPermission(err) {
return fmt.Errorf("fix permissions on %s: %w", filepath.Dir(dest), err)
}
return err
} Prevention
- Run 'cscli hub update' before tests so the hub tree is complete.
- Run tests as a user with write access to the runtime directory.
- Check disk space in CI before long test runs.
When it happens
Trigger: installScenario -> installScenarioItem where Copy(sourcePath, hubDirScenarioPath) fails: the hub scenario file is absent, the destination directory doesn't exist/hasn't been created with correct permissions, or disk is full.
Common situations: Corrupted or partially updated hub (cscli hub update interrupted); read-only filesystem or container; the test runtime directory was pre-created by root and tests run as another user.
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 scenario from '%s' to '%s': %w
- unable to copy '%s' to '%s': %w
- can't get absolute path of '%s': %w
- unable to symlink scenario '%s' to '%s': %w
- unable to create folder '%s': %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/ff46cf25330f68fb.
Report an issue: GitHub.