crowdsecurity/crowdsec · error

unable to copy '%s' to '%s': %w

Error message

unable to copy '%s' to '%s': %w

What it means

This error is returned by HubTestItem.Run in pkg/hubtest when the copy of the test's template crowdsec config file (t.TemplateConfigPath) into the test runtime folder (t.RuntimeConfigFilePath) fails. It wraps the underlying os-level error (typically the source file missing, or the destination being unwritable). It means the hubtest runtime environment could not be prepared, so the test never runs.

Source

Thrown at pkg/hubtest/hubtest_item.go:619

func (t *HubTestItem) Run(ctx context.Context, patternDir string) error {
	var err error

	t.Success = false
	t.ErrorsList = make([]string, 0)

	// create runtime, data, hub, result folders
	if err = createDirs([]string{t.RuntimePath, t.RuntimeDBDir, t.RuntimeHubConfig.InstallDataDir, t.RuntimeHubPath, t.ResultsPath}); err != nil {
		return err
	}

	if err = Copy(t.HubIndexFile, filepath.Join(t.RuntimeHubPath, ".index.json")); err != nil {
		return fmt.Errorf("unable to copy .index.json file in '%s': %w", filepath.Join(t.RuntimeHubPath, ".index.json"), err)
	}

	// copy template config file to runtime folder
	if err = Copy(t.TemplateConfigPath, t.RuntimeConfigFilePath); err != nil {
		return fmt.Errorf("unable to copy '%s' to '%s': %w", t.TemplateConfigPath, t.RuntimeConfigFilePath, err)
	}

	// copy template profile file to runtime folder
	if err = Copy(t.TemplateProfilePath, t.RuntimeProfileFilePath); err != nil {
		return fmt.Errorf("unable to copy '%s' to '%s': %w", t.TemplateProfilePath, t.RuntimeProfileFilePath, err)
	}

	// copy template simulation file to runtime folder
	if err = Copy(t.TemplateSimulationPath, t.RuntimeSimulationFilePath); err != nil {
		return fmt.Errorf("unable to copy '%s' to '%s': %w", t.TemplateSimulationPath, t.RuntimeSimulationFilePath, err)
	}

	// copy template patterns folder to runtime folder
	if err = CopyDir(patternDir, t.RuntimePatternsPath); err != nil {
		return fmt.Errorf("unable to copy 'patterns' from '%s' to '%s': %w", patternDir, t.RuntimePatternsPath, err)
	}

	// create the appsec-configs dir

View on GitHub (pinned to 909b515798)

Solutions

  1. Check the wrapped error: if it says 'no such file or directory' for the source, verify t.TemplateConfigPath exists before running the test.
  2. Verify the runtime directory (t.RuntimePath) exists and is writable by the current user; re-run createDirs or remove stale runtime folders.
  3. Run the hub test with sufficient permissions (e.g. the same user that owns the crowdsec source tree).
  4. Check free disk space and that the destination path is not a directory.

Example fix

// before: calling Run with a missing template config
item.Run(ctx, patternDir) // fails if config.yaml template absent
// after: pre-validate templates
if _, err := os.Stat(item.TemplateConfigPath); err != nil {
    return fmt.Errorf("template config missing: %w", err)
}
if err := item.Run(ctx, patternDir); err != nil { ... }
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(item.TemplateConfigPath); err != nil {
    return fmt.Errorf("config template missing: %w", err)
}
if err := os.MkdirAll(filepath.Dir(item.RuntimeConfigFilePath), 0o755); err != nil {
    return fmt.Errorf("runtime dir not writable: %w", err)
}

Try / catch

if err := item.Run(ctx, patternDir); err != nil {
    var perr *os.PathError
    if errors.As(err, &perr) {
        log.Errorf("copy failed for %s: %v", perr.Path, perr.Err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling cscli hubtest run (which invokes HubTestItem.Run) when the template config file referenced by t.TemplateConfigPath does not exist, when t.RuntimeConfigFilePath's parent directory was not created or is not writable, or when disk I/O fails mid-copy.

Common situations: Running hub tests from a source tree where the config template was not built/copied; running as a user without write permission on the test runtime directory; read-only filesystem or full disk; a partially-cleaned runtime folder from a previous failed test run.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06). Data as JSON: /api/errors/49de8d34d6944d24. Report an issue: GitHub.