{"record":{"id":"3f4fc4b8f746cc38","repo":"multica-ai/multica","slug":"create-hermes-memory-staging-dir-in-s-w","errorCode":null,"errorMessage":"create hermes memory staging dir in %s: %w","messagePattern":"create hermes memory staging dir in (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/internal/daemon/execenv/hermes_memory.go","lineNumber":268,"sourceCode":"\treturn nil\n}\n\n// newHermesStoreStaging creates the scratch directory a store migration copies\n// into. It is a sibling of the store so the promoting rename stays within one\n// filesystem, and dot-prefixed so it is obvious it is not a store of its own.\n// Shared by the memory migration here and the session-database migration in\n// hermes_sessions.go: both delete their source once the copy reports success,\n// so both need the same all-or-nothing publish.\n// MkdirTemp already creates it 0700, the same mode the store itself is created\n// with, so there is no follow-up chmod that could fail and strand it.\nfunc newHermesStoreStaging(storeDir string) (string, error) {\n\tparent := filepath.Dir(storeDir)\n\tif err := os.MkdirAll(parent, 0o700); err != nil {\n\t\treturn \"\", fmt.Errorf(\"create hermes memory store parent %s: %w\", parent, err)\n\t}\n\tstaging, err := os.MkdirTemp(parent, \".\"+filepath.Base(storeDir)+\".migrating-\")\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"create hermes memory staging dir in %s: %w\", parent, err)\n\t}\n\treturn staging, nil\n}\n\n// promoteHermesStoreStaging publishes a fully-copied staging dir as the store,\n// reporting whether this caller won. The empty store dir (if any) is removed\n// first: os.Remove only succeeds on an empty directory, so a store another task\n// already populated makes this a no-op, and Windows rejects a rename onto an\n// existing directory outright.\n//\n// Losing the race is not an error — the winner's store holds the same agent's\n// state — but it has to be positively confirmed, never inferred from any\n// failure. The caller deletes the source directory whenever this returns\n// (false, nil), so a permission error, a read-only filesystem or a Windows\n// sharing violation must fail closed instead of passing for \"someone else\n// published\".\n//\n// published answers \"did a competitor already publish real state here?\" and is","sourceCodeStart":250,"sourceCodeEnd":286,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/daemon/execenv/hermes_memory.go#L250-L286","documentation":"Returned by newHermesStoreStaging when os.MkdirTemp fails to create the dot-prefixed scratch dir (.<store>.migrating-*) inside the store's parent. This staging dir is what the migration copies into before one atomic rename publishes it, so failure stops migration before anything is touched.","triggerScenarios":"os.MkdirTemp in the store parent fails: parent not writable (EACCES), disk full (ENOSPC), too many open files (EMFILE) under heavy concurrency, or file-name pattern issues on exotic filesystems.","commonSituations":"Disk-full on the profile volume during an upgrade with large memories; read-only mount; heavy concurrent task starts exhausting temp-dir handles.","solutions":["Freeze space/inodes on the volume containing the profile dir and retry the task.","Fix write permissions on <profile>/hermes-state/<agent> for the daemon user.","If it recurs under many concurrent tasks, stagger task starts to reduce simultaneous migrations."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Cheap canary: if a temp dir can be made, MkdirTemp will likely succeed.\nif _, err := os.MkdirTemp(parent, \".canary-\"); err != nil {\n    return fmt.Errorf(\"staging area unusable: %w\", err)\n} else { os.Remove(canary) }","typeGuard":null,"tryCatchPattern":"if _, err := newHermesStoreStaging(storeDir); err != nil && isTransient(err) {\n    // EMFILE/ENOSPC class: back off once, then retry\n    time.Sleep(time.Second)\n    _, err = newHermesStoreStaging(storeDir)\n}","preventionTips":["Cap simultaneous task starts to avoid temp-dir handle storms","Monitor ENOSPC/EMFILE in daemon logs","Keep migrations off read-only mounts"],"tags":["filesystem","hermes","migration","disk-full","temp-dir"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}