crowdsecurity/crowdsec · error
unable to copy scenario from '%s' to '%s': %w
Error message
unable to copy scenario from '%s' to '%s': %w
What it means
After creating the runtime scenarios directory, installScenarioCustomFrom copies the custom scenario file into it via Copy; failure is reported with source and destination paths plus the underlying cause. It means the custom scenario file could not be read or the destination file could not be written.
Source
Thrown at pkg/hubtest/scenario.go:62
}
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, nil
}
itemTypeDirDest := fmt.Sprintf("%s/scenarios/", t.RuntimePath)
if err := os.MkdirAll(itemTypeDirDest, os.ModePerm); err != nil {
return false, fmt.Errorf("unable to create folder '%s': %w", itemTypeDirDest, err)
}
scenarioFileName := filepath.Base(customScenarioPath)
scenarioFileDest := filepath.Join(itemTypeDirDest, scenarioFileName)
if err := Copy(customScenarioPath, scenarioFileDest); err != nil {
return false, fmt.Errorf("unable to copy scenario from '%s' to '%s': %w", customScenarioPath, scenarioFileDest, err)
}
return true, nil
}
func (t *HubTestItem) installScenarioCustom(scenario string) error {
for _, customPath := range t.CustomItemsLocation {
found, err := t.installScenarioCustomFrom(scenario, customPath)
if err != nil {
return err
}
if found {
return nil
}
}
return fmt.Errorf("couldn't find custom scenario '%s' in the following location: %+v", scenario, t.CustomItemsLocation)View on GitHub (pinned to 909b515798)
Solutions
- Verify the source file exists and is readable by the running user (ls -la customScenarioPath).
- Fix permissions on the destination runtime/scenarios directory.
- If the destination exists as a directory, remove it and re-run.
- Check the wrapped error (%w) for the exact syscall failure.
Example fix
// before
Copy("./custom/scen.yaml", "/runtime/scenarios/scen.yaml") // source unreadable
// after
chmod +r ./custom/scen.yaml && Copy("./custom/scen.yaml", "/runtime/scenarios/scen.yaml") Defensive patterns
Strategy: validation
Validate before calling
if fi, err := os.Stat(customScenarioPath); err != nil || fi.IsDir() {
return fmt.Errorf("custom scenario %s missing or a directory", customScenarioPath)
} Try / catch
if err := Copy(src, dst); err != nil {
var perr *os.PathError
if errors.As(err, &perr) {
return fmt.Errorf("copy failed at %s (op=%s): %w", perr.Path, perr.Op, err)
}
return err
} Prevention
- Verify readability of custom scenario files before running tests.
- Ensure the destination file is not a directory and is writable.
- Keep CustomItemsLocation free of broken symlinks.
When it happens
Trigger: installScenarioCustom -> installScenarioCustomFrom where Copy(customScenarioPath, scenarioFileDest) fails: source file unreadable/missing (e.g. broken symlink), destination not writable, or disk full.
Common situations: CustomItemsLocation points at a directory where the scenario entry is a broken symlink; permission mismatch between the file's owner and the test runner; the destination path already exists as a directory.
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 '%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/2bc5213bc9ad2a1b.
Report an issue: GitHub.