{"record":{"id":"1cbec38391355caa","repo":"multica-ai/multica","slug":"read-overlay-home-w","errorCode":null,"errorMessage":"read overlay home: %w","messagePattern":"read overlay home: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/daemon/execenv/hermes_home.go","lineNumber":551,"sourceCode":"\t\t\tcontinue\n\t\t}\n\t\tsrc := filepath.Join(sharedHome, name)\n\t\tdst := filepath.Join(hermesHome, name)\n\t\tif err := linkSharedHermesEntry(src, dst); err != nil {\n\t\t\treturn fmt.Errorf(\"mirror %s: %w\", name, err)\n\t\t}\n\t\tmirrored[name] = struct{}{}\n\t}\n\treturn reconcileMirroredEntries(hermesHome, mirrored)\n}\n\n// reconcileMirroredEntries removes overlay entries that are neither overlay-owned\n// nor currently mirrored from the shared home, so a shared entry deleted between\n// runs (or a Windows copy-fallback left behind) doesn't survive as stale state.\nfunc reconcileMirroredEntries(hermesHome string, mirrored map[string]struct{}) error {\n\tentries, err := os.ReadDir(hermesHome)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"read overlay home: %w\", err)\n\t}\n\tfor _, entry := range entries {\n\t\tname := entry.Name()\n\t\tif isHermesOverlayOwnedEntry(name) {\n\t\t\tcontinue\n\t\t}\n\t\tif _, keep := mirrored[name]; keep {\n\t\t\tcontinue\n\t\t}\n\t\tif err := os.RemoveAll(filepath.Join(hermesHome, name)); err != nil {\n\t\t\treturn fmt.Errorf(\"reconcile stale %s: %w\", name, err)\n\t\t}\n\t}\n\treturn nil\n}\n\n// prepareHermesTaskLocalState migrates an overlay built by an older daemon away\n// from the shared Hermes SQLite session store. Without the marker, state.db and","sourceCodeStart":533,"sourceCodeEnd":569,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/daemon/execenv/hermes_home.go#L533-L569","documentation":"reconcileMirroredEntries could not list the task-local overlay home (os.ReadDir(hermesHome)) while pruning entries that are no longer mirrored from the shared home. The overlay directory itself is unreadable or was removed out from under the prepare step. The reconciliation exists so deleted-in-shared-home entries and Windows copy-fallback leftovers do not survive as stale state.","triggerScenarios":"The generated overlay dir (env RootDir/hermes-home) has mode 000, was deleted concurrently (env teardown/GC racing a task start), or sits on a failing filesystem.","commonSituations":"Cloud GC loop wiping env dirs at the same moment a task starts; a previous crash left a partially-created overlay with wrong permissions; disk-full filesystem going read-only.","solutions":["Check the overlay dir exists and is readable by the daemon user: `ls -la <envRoot>/hermes-home`.","Delete the whole overlay dir and let the next prepare rebuild it from the shared home.","Serialize env GC/teardown against task start so the overlay is not deleted mid-prepare.","Check dmesp/logs for underlying I/O errors (read-only remount, disk failure) and remount/replace the volume."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if fi, err := os.Stat(hermesHome); err != nil {\n\treturn fmt.Errorf(\"overlay home missing before reconcile: %w\", err)\n} else if !fi.IsDir() || fi.Mode().Perm()&0o400 == 0 {\n\treturn fmt.Errorf(\"overlay home not a readable dir: %s\", hermesHome)\n}","typeGuard":null,"tryCatchPattern":"if err := reconcileMirroredEntries(hermesHome, mirrored); err != nil {\n\tif errors.Is(err, fs.ErrNotExist) {\n\t\t// overlay vanished (GC race): recreate from scratch instead of failing\n\t\treturn mirrorSharedHermesHome(sharedHome, hermesHome, logger)\n\t}\n\treturn err\n}","preventionTips":["Serialize env GC/teardown with task start (lock per env RootDir).","Treat the overlay dir as disposable: on odd failures, delete and rebuild it.","Monitor for read-only filesystems under the env root."],"tags":["filesystem","hermes","execenv","concurrency","gc"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}