GopeedLab/gopeed · warning
script file does not exist: %s
Error message
script file does not exist: %s
What it means
Returned by executeScriptAtPath (script.go:57-65) when a configured script hook path does not exist on disk at execution time. Scripts are fired asynchronously after download events (triggerScripts spawns executeScripts), so the failure is not raised to the download flow; it is logged as a warning with the offending path (script.go:155). The check uses os.Stat with IsNotExist, so any missing path (typo, moved file, wrong working directory) triggers it.
Source
Thrown at pkg/download/script.go:64
}
if len(paths) > 0 {
return paths
}
}
return nil
}
// executeScriptAtPath executes a single script with the given data
// Returns any error that occurred during execution
func (d *Downloader) executeScriptAtPath(scriptPath string, data *ScriptData) error {
if scriptPath == "" {
return fmt.Errorf("script path is empty")
}
// Check if script file exists
if _, err := os.Stat(scriptPath); os.IsNotExist(err) {
return fmt.Errorf("script file does not exist: %s", scriptPath)
}
// Determine the script interpreter based on file extension
var cmd *exec.Cmd
ext := filepath.Ext(scriptPath)
switch ext {
case ".sh", ".bash":
cmd = exec.Command("bash", scriptPath)
case ".py":
cmd = exec.Command("python3", scriptPath)
case ".js":
cmd = exec.Command("node", scriptPath)
case ".bat", ".cmd":
// Windows batch files
if runtime.GOOS == "windows" {
cmd = exec.Command("cmd", "/c", scriptPath)
} else {View on GitHub (pinned to 7b7327ffb3)
Solutions
- Correct the path in the script settings to an existing file
- Prefer absolute paths over relative ones so resolution does not depend on process CWD
- For containers, mount the script into the container and reference the in-container path
- Check the gopeed log for the 'script: failed to execute' warning to see the exact failing path
Example fix
# before (config)
"script": { "enable": true, "paths": ["notify.sh"] } # relative, CWD-dependent
# after
"script": { "enable": true, "paths": ["/opt/gopeed/scripts/notify.sh"] } # absolute, mounted in container Defensive patterns
Strategy: validation
Validate before calling
for _, p := range cfg.Script.Paths {
if _, err := os.Stat(p); err != nil {
return fmt.Errorf("script hook %q not found", p)
}
} Try / catch
if err := d.executeScriptAtPath(path, data); err != nil {
log.Warn("script hook failed", "path", path, "err", err)
} Prevention
- Use absolute paths in script hook configuration
- Mount script files into containers and reference the in-container path
- Validate hook paths at settings-save time, not at fire time
- Watch logs for 'script: failed to execute' warnings after config changes
When it happens
Trigger: DownloaderStoreConfig.Script.Paths contains a path that does not exist when DOWNLOAD_DONE/DOWNLOAD_ERROR fires: a typo, a file deleted after the config was saved, a relative path resolved against a different CWD (desktop app vs systemd/docker service), or a config synced from another machine.
Common situations: Absolute home-directory paths like /home/user/notify.sh that do not exist in a Docker deployment; scripts moved during refactoring without updating settings; portable installs where the config travels but the script does not; NAS environments with different mount points.
Related errors
- batch files (.bat/.cmd) are only supported on Windows
- download directory is not in white list
- manifest.json not found
- no parts found for %s
- webhook URL is empty
AI-assisted analysis of GopeedLab/gopeed@7b7327ffb3 (2026-08-16).
Data as JSON: /api/errors/553e562b22e09c04.
Report an issue: GitHub.