crowdsecurity/crowdsec · warning
%s is already installed at %s
Error message
%s is already installed at %s
What it means
Item.PathForInstall computes the symlink target for installing an item. If i.State.IsInstalled() is true, the item already has a local symlink, and reinstalling would overwrite/conflict, so it errors instead.
Source
Thrown at pkg/cwhub/item.go:123
Description string `json:"description,omitempty" yaml:"description,omitempty"`
Content string `json:"content,omitempty" yaml:"-"`
References []string `json:"references,omitempty" yaml:"references,omitempty"`
// NOTE: RemotePath could be derived from the other fields
RemotePath string `json:"path,omitempty" yaml:"path,omitempty"` // path relative to the base URL eg. /parsers/stage/author/file.yaml
Version string `json:"version,omitempty" yaml:"version,omitempty"` // the last available version
Versions map[string]ItemVersion `json:"versions,omitempty" yaml:"-"` // all the known versions
// The index contains the dependencies of the "latest" version (collections only)
Dependencies
}
// PathForInstall returns the path to use for the install symlink
// (eg. /etc/crowdsec/collections/xyz.yaml).
// Returns an error if an item is already installed or if the path goes outside of the install dir.
func (i *Item) PathForInstall() (string, error) {
if i.State.IsInstalled() {
return "", fmt.Errorf("%s is already installed at %s", i.FQName(), i.State.LocalPath)
}
p := i.Type
if i.Stage != "" {
p = filepath.Join(p, i.Stage)
}
return SafePath(i.hub.local.InstallDir, filepath.Join(p, i.FileName))
}
// PathForDownload returns the path to use to store the item's file from the hub
// (eg. /etc/crowdsec/hub/collections/author/xyz.yaml).
// Raises an error if the path goes outside of the hub dir.
func (i *Item) PathForDownload() (string, error) {
path, err := SafePath(i.hub.local.HubDir, i.RemotePath)
if i.State.IsDownloaded() && path != i.State.DownloadPath {
// A hub item with the same name is at a different location.View on GitHub (pinned to 909b515798)
Solutions
- Skip the install if the item is already installed (check i.State.IsInstalled() first)
- Use `cscli collections install <name> --force` (or the corresponding upgrade path) to overwrite
- Remove the existing symlink at State.LocalPath before installing
- Use item.Upgrade instead of Install when intending to refresh
Example fix
// before
path, err := item.PathForInstall()
// after
if !item.State.IsInstalled() {
path, err := item.PathForInstall()
...
} Defensive patterns
Strategy: validation
Validate before calling
if item.State.IsInstalled() {
return nil // or item.Upgrade()
} Try / catch
if err := item.PathForInstall(); err != nil {
if item.State.IsInstalled() {
// already installed: skip or upgrade
return nil
}
return err
} Prevention
- Check State.IsInstalled() before every install call
- Use upgrade paths instead of repeated installs
- Clean up orphaned symlinks in the install dir
When it happens
Trigger: Calling CreateInstallLink / PathForInstall on an item whose State shows an existing local installation (LocalPath set and installed flag true).
Common situations: Running `cscli hub install` twice without --force; scripted installs that don't check installed state first; a leftover symlink from a previous install making the item look installed.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- too many levels of symbolic links
- file '%s' is not from hub '%s' nor from the configuration di
- %s isn't managed by hub
- while reading symlink: %w
- while removing symlink: %w
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/47db6a252eb60ab6.
Report an issue: GitHub.