multica-ai/multica · error
remove stale %s: %w
Error message
remove stale %s: %w
What it means
linkSharedHermesEntry found an existing entry at the destination whose symlink does not already point at src, tried os.RemoveAll to clear it before recreating the link, and the removal failed. The function is idempotent by design (matching link left alone, anything else replaced), so this means the overlay holds an entry the daemon cannot delete.
Source
Thrown at server/internal/daemon/execenv/hermes_home.go:615
}
return writeFileAtomic(marker, []byte("task-local Hermes state\n"), 0o600)
}
// linkSharedHermesEntry symlinks dst → src, idempotent across Reuse: an existing
// link already pointing at src is left alone; anything else is removed and
// recreated so the overlay never drifts from the shared home. A dangling source
// (a broken symlink in the user's home) is skipped, not failed. Directories use
// createDirLink and files createFileLink so the Windows copy fallbacks match the
// entry kind.
func linkSharedHermesEntry(src, dst string) error {
if fi, err := os.Lstat(dst); err == nil {
if fi.Mode()&os.ModeSymlink != 0 {
if target, err := os.Readlink(dst); err == nil && target == src {
return nil
}
}
if err := os.RemoveAll(dst); err != nil {
return fmt.Errorf("remove stale %s: %w", dst, err)
}
}
info, err := os.Stat(src) // follow the link to decide dir vs file
if err != nil {
if os.IsNotExist(err) {
return nil // dangling source in the user's home — nothing to link
}
return fmt.Errorf("stat %s: %w", src, err)
}
if info.IsDir() {
return createDirLink(src, dst)
}
return createFileLink(src, dst)
}
// writeDerivedHermesConfig writes the task-local config.yaml: the user's config
// with `skills.external_dirs` set to their existing external dirs plus the sharedView on GitHub (pinned to 2c0912b6ec)
Solutions
- Check ownership and mode of the named dst path: `ls -la`; chown/chmod it (or its parent) so the daemon can unlink.
- Terminate any process still using the overlay entry, then retry the task.
- Reset the overlay wholesale (delete hermes-home under the env RootDir) — every mirrored entry is regenerated from the shared home.
- Run the daemon under one stable UID so this class of drift cannot occur.
Defensive patterns
Strategy: try-catch
Try / catch
if err := linkSharedHermesEntry(src, dst); err != nil {
var pe *os.PathError
if errors.As(err, &pe) && errors.Is(pe.Err, syscall.EACCES) {
// undeletable stale dst: drop whole overlay and let caller rebuild
return os.RemoveAll(filepath.Dir(dst))
}
return err
} Prevention
- Keep one daemon UID per env so every dst entry is deletable by later runs.
- Close/stop all users of the overlay before reuse.
- On Windows, exclude env roots from AV/indexing to avoid unlink sharing violations.
When it happens
Trigger: Destination entry is owned by another user or read-only; a running process holds it open (Windows sharing violation); immutable flag or sticky-bit dir prevents unlink; the entry is a directory the daemon lacks write permission on for recursive removal.
Common situations: Overlay reused across runs under different UIDs/privileges; previous task's process still running out of the overlay; antivirus or indexer briefly pinning files on Windows.
Related errors
- mirror %s: %w
- stat %s: %w
- mint PAT: response missing token
- daemon profile is not resolved yet; token sync skipped
- runtime local skill discovery timed out
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/2f15ec9f1afa68f7.
Report an issue: GitHub.