multica-ai/multica · error
runtime local skill discovery timed out
Error message
runtime local skill discovery timed out
What it means
Wrap thrown by prepareHermesHome when mirrorSharedHermesHome fails. The mirror copies the shared hermes home's contents into the per-task overlay so the hermes CLI sees its expected config/assets while task-local overrides are layered on top. The overlay fails closed: a broken mirror means Hermes could run without its expected configuration, so the whole prepare aborts.
Source
Thrown at packages/core/runtimes/local-skills.ts:38
// the daemon to actually run the import.
//
// Timeout invariant: IMPORT_POLL_TIMEOUT_MS must exceed
// runtimeLocalSkillPendingTimeout + runtimeLocalSkillRunningTimeout
// (server/internal/handler/runtime_local_skills.go).
// See also IMPORT_CONCURRENCY in packages/views/.../runtime-local-skill-import-panel.tsx
// and maxLocalSkillImportBatch in server/internal/handler/daemon.go.
const IMPORT_POLL_TIMEOUT_MS = 4 * 60_000; // 4 minutes
export async function resolveRuntimeLocalSkills(
runtimeId: string,
): Promise<RuntimeLocalSkillsResult> {
const initial = await api.initiateListLocalSkills(runtimeId);
const start = Date.now();
let current = initial;
while (current.status === "pending" || current.status === "running") {
if (Date.now() - start > POLL_TIMEOUT_MS) {
throw new Error("runtime local skill discovery timed out");
}
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
current = await api.getListLocalSkillsResult(runtimeId, initial.id);
}
if (current.status === "failed" || current.status === "timeout") {
throw new Error(current.error || "runtime local skill discovery failed");
}
return {
skills: current.skills ?? [],
supported: current.supported,
mcpServers: current.mcp_servers ?? [],
mcpSupported: current.mcp_supported === true,
};
}
export async function resolveRuntimeLocalSkillImport(View on GitHub (pinned to 2c0912b6ec)
Solutions
- Read the wrapped error for the failing source path; make it readable by the daemon user (chmod/chown) or remove it if it is cache/junk.
- Prune large caches from the shared home or enlarge env-root storage so the mirror fits.
- Stabilize the shared home's mount (avoid NFS soft mounts/timeouts) or relocate the home to local disk.
- Replace unusual file types (sockets, broken symlinks) in the shared home, or point HermesSourceHome at a lean profile-specific home.
Example fix
# before: shared home holds root-owned cache the daemon cannot read $ find ~/.hermes -not -readable -o -user root | head /home/user/.hermes/cache/blob (root) # after $ sudo chown -R user:user /home/user/.hermes/cache $ rm -rf /home/user/.hermes/cache # or just delete the cache
Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: every regular file in the shared home must be readable
err := filepath.WalkDir(sharedHome, func(p string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.Type().IsRegular() {
if fi, err := d.Info(); err == nil && fi.Mode().Perm()&0o400 == 0 {
return fmt.Errorf("unreadable file in shared home: %s", p)
}
}
return nil
}) Try / catch
if err := prepareHermesHome(...); err != nil {
if strings.Contains(err.Error(), "mirror shared hermes home") {
// wrapped error names the failing source file: chmod/chown it or purge caches, then retry
}
} Prevention
- Keep the shared hermes home free of caches, sockets, and root-owned files.
- Run periodic permission audits on the shared home.
- Prefer lean per-profile homes as HermesSourceHome.
When it happens
Trigger: mirrorSharedHermesHome(sharedHome, hermesHome, logger) errors — unreadable files in the shared home (permission drift), special file types it refuses to copy, destination name collisions inside the overlay, or disk exhaustion while copying.
Common situations: Shared home contains files owned by root or with restrictive modes the daemon cannot read; the shared home grew large (caches, many profiles) and overflows env-root; shared home on a flaky NFS mount; symlinks/sockets inside the home that the mirror rejects.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- mint PAT: response missing token
- daemon profile is not resolved yet; token sync skipped
- runtime local skill import failed
- mint PAT: target API URL not set
- API error: ${res.status} ${res.statusText}
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/e7b587b405df27b9.
Report an issue: GitHub.