multica-ai/multica · error
runtime local skill import timed out
Error message
runtime local skill import timed out
What it means
Wrap thrown by prepareHermesHome when writeDerivedHermesEnv fails. This writes the overlay's .env: the source home's .env with any HERMES_HOME assignment stripped, plus a pinned HERMES_HOME appended last so it wins (Hermes loads <HERMES_HOME>/.env with override=True right after profile resolution). The file is always written — even with no source .env — 0600 via atomic replace, because it can hold API-key secrets. A write failure is fatal since an absent .env would let Hermes' project-.env fallback relocate the home and break skill binding and memory isolation.
Source
Thrown at packages/core/runtimes/local-skills.ts:66
return {
skills: current.skills ?? [],
supported: current.supported,
mcpServers: current.mcp_servers ?? [],
mcpSupported: current.mcp_supported === true,
};
}
export async function resolveRuntimeLocalSkillImport(
runtimeId: string,
payload: CreateRuntimeLocalSkillImportRequest,
): Promise<RuntimeLocalSkillImportResult> {
const initial = await api.initiateImportLocalSkill(runtimeId, payload);
const start = Date.now();
let current = initial;
while (current.status === "pending" || current.status === "running") {
if (Date.now() - start > IMPORT_POLL_TIMEOUT_MS) {
throw new Error("runtime local skill import timed out");
}
await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS));
current = await api.getImportLocalSkillResult(runtimeId, initial.id);
}
if (current.status === "conflict") {
if (!current.conflict) {
throw new Error("runtime local skill import conflict missing details");
}
return {
status: "conflict",
conflict: current.conflict,
};
}
if (current.status === "failed" || current.status === "timeout") {
throw new Error(current.error || "runtime local skill import failed");
}View on GitHub (pinned to 2c0912b6ec)
Solutions
- Check ownership/permissions of <envRoot>/hermes-home/.env and repair or remove it so the atomic replace can proceed.
- Free disk space on the env-root volume.
- Ensure env-root is on a POSIX filesystem supporting rename(2).
- If reading the source .env is the failing part (see the wrapped 'read shared .env' error), fix that file's permissions first.
Example fix
# before: stale overlay .env owned by root blocks atomic replace $ ls -l /var/lib/app/envs/task-9/hermes-home/.env -rw------- 1 root root ... # after $ chown daemonuser:daemongroup /var/lib/app/envs/task-9/hermes-home/.env # or delete it
Defensive patterns
Strategy: try-catch
Validate before calling
envFile := filepath.Join(envRoot, "hermes-home", ".env")
if fi, err := os.Stat(envFile); err == nil && !fi.Mode().IsRegular() {
return fmt.Errorf("overlay .env path is not a regular file: %s", envFile)
} Try / catch
if err := prepareHermesHome(...); err != nil {
if strings.Contains(err.Error(), "derive hermes .env") {
// check the wrapped error: source read perms (see 'read shared .env') vs overlay write; fix and retry prepare
}
} Prevention
- Repair ownership of stale overlay .env files when recycling env-roots.
- Keep env-root on rename-capable local filesystems.
- Disk-space alerts on env-root volumes.
When it happens
Trigger: writeDerivedHermesEnv(sharedHome, hermesHome) errors — reading the source .env fails with a non-NotExist error (handled by a narrower wrap), stripping/serialization fails, or the atomic replace into hermes-home fails on permissions or full disk.
Common situations: Overlay .env left owned by a previous daemon user in a recycled env-root; disk full at the moment of the atomic rename; env-root on a filesystem that does not support the rename-based atomic write.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- daemon profile is not resolved yet; token sync skipped
- runtime local skill import failed
- mint PAT: target API URL not set
- mint PAT: response missing token
- API error: ${res.status} ${res.statusText}
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/2b3095ac888f78b4.
Report an issue: GitHub.