multica-ai/multica · error
read shared home: %w
Error message
read shared home: %w
What it means
mirrorSharedHermesHome could not list the shared Hermes home (os.ReadDir) and the failure was not 'does not exist'. The daemon builds each task's Hermes overlay by symlinking entries out of the user's real home, so an unreadable source home aborts overlay construction. The wrapped error is the underlying *PathError (permission denied, not-a-directory, I/O error).
Source
Thrown at server/internal/daemon/execenv/hermes_home.go:527
return strings.TrimSpace(s[:eq])
}
// mirrorSharedHermesHome symlinks every top-level entry of the shared ~/.hermes/
// into the per-task home except the overlay-owned entries, then reconciles the
// destination so entries removed from the shared home (or left over from a prior
// reuse) don't linger as readable stale state. Symlinks share state with the
// user's real home (auth/OAuth refreshes propagate, no credential copy lingers
// in task scratch). The shared home itself is never written — we only read it
// and create links pointing into it.
func mirrorSharedHermesHome(sharedHome, hermesHome string, logger *slog.Logger) error {
entries, err := os.ReadDir(sharedHome)
if err != nil {
if os.IsNotExist(err) {
// No shared home to mirror. The derived config + bound skills still
// give Hermes a working home, so this is not fatal on its own.
return reconcileMirroredEntries(hermesHome, nil)
}
return fmt.Errorf("read shared home: %w", err)
}
mirrored := make(map[string]struct{}, len(entries))
for _, entry := range entries {
name := entry.Name()
if isHermesOverlayOwnedEntry(name) {
continue
}
src := filepath.Join(sharedHome, name)
dst := filepath.Join(hermesHome, name)
if err := linkSharedHermesEntry(src, dst); err != nil {
return fmt.Errorf("mirror %s: %w", name, err)
}
mirrored[name] = struct{}{}
}
return reconcileMirroredEntries(hermesHome, mirrored)
}
// reconcileMirroredEntries removes overlay entries that are neither overlay-ownedView on GitHub (pinned to 2c0912b6ec)
Solutions
- Check the resolved shared home: run the daemon env with HERMES_HOME printed, verify `ls -la <sharedHome>` works as the daemon user.
- Fix ownership/permissions on the shared home (chown/chmod so the daemon's UID can read it).
- If HERMES_HOME points at a wrong path (file, mountpoint), point it at the real Hermes home or unset it to use the platform default.
- If the volume is flaky (NFS/network share), remount or move the Hermes home to local disk and retry the task.
Defensive patterns
Strategy: validation
Validate before calling
if fi, err := os.Stat(sharedHome); err != nil || !fi.IsDir() {
return fmt.Errorf("shared hermes home unusable: %v", err)
}
if entries, err := os.ReadDir(sharedHome); err != nil {
return fmt.Errorf("shared hermes home not listable: %w", err)
} else {
_ = entries // readable
} Try / catch
if err := mirrorSharedHermesHome(sharedHome, hermesHome, logger); err != nil {
var pe *os.PathError
if errors.As(err, &pe) {
log.Printf("shared home path failure at %s: %v", pe.Path, pe.Err)
}
return err // overlay cannot be trusted if the source home is unreadable
} Prevention
- Run the daemon as the user who owns the Hermes home, or grant that UID read access.
- Smoke-test env setup with `ls -la $HERMES_HOME` under the daemon account.
- Keep the Hermes home on local, healthy disk rather than network shares.
When it happens
Trigger: Running a task whose resolved HERMES_HOME (or the platform default ~/.hermes, %LOCALAPPDATA%\hermes on Windows) exists but cannot be listed: mode 000, owned by another user, the path is actually a file, or the filesystem errors (NFS stale handle, detached volume).
Common situations: Daemon runs as a different user/service account than the one owning ~/.hermes; HERMES_HOME pointed at a file or a OneDrive/enterprise share with restricted ACLs; home directory on a network mount that went away mid-run.
Related errors
- mint PAT: response missing token
- daemon profile is not resolved yet; token sync skipped
- runtime local skill discovery timed out
- runtime local skill import failed
- stat state marker: %w
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/68bb7ada481af2b2.
Report an issue: GitHub.