multica-ai/multica · error
runtime local skill discovery failed
Error message
runtime local skill discovery failed
What it means
Wrap thrown by prepareHermesHome when writeDerivedHermesConfig fails. The derived config is re-derived from the shared home's config plus the task's env overrides and written into the overlay; it can hold inline api_key secrets. Fail-closed by design: a Hermes that would boot without the derived config could miss its providers/keys, so prepare aborts instead.
Source
Thrown at packages/core/runtimes/local-skills.ts:45
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(
runtimeId: string,
payload: CreateRuntimeLocalSkillImportRequest,
): Promise<RuntimeLocalSkillImportResult> {
const initial = await api.initiateImportLocalSkill(runtimeId, payload);
const start = Date.now();
let current = initial;
View on GitHub (pinned to 2c0912b6ec)
Solutions
- Validate the shared home's config file parses (e.g. `hermes` CLI or a local parse) and repair syntax errors.
- Sanitize env override values passed via params.HermesEnv; drop keys that are not valid config inputs.
- Fix write permissions/ownership of the overlay's config path or delete the stale overlay.
- Free disk space and retry.
Example fix
# before: invalid line in shared config $ cat ~/.hermes/config.toml api_key = broken ← syntax error # after api_key = "sk-..." # quoted, valid
Defensive patterns
Strategy: validation
Validate before calling
if _, err := toml.ParseFile(filepath.Join(sharedHome, "config.toml")); err != nil { // or hermes CLI check
return fmt.Errorf("shared hermes config invalid: %w", err)
} Try / catch
if err := prepareHermesHome(...); err != nil {
if strings.Contains(err.Error(), "derive hermes config") {
// surface the wrapped parse/write error; repair the shared config or env overrides; no silent minimal-config fallback
}
} Prevention
- Lint the shared hermes config on change (parse check).
- Whitelist which HermesEnv keys may override config.
- Version the hermes config format with the daemon upgrade.
When it happens
Trigger: writeDerivedHermesConfig(sharedHome, hermesHome, env, logger) errors — the shared config is unreadable or unparseable, a required value cannot be rendered, or the derived file cannot be written into hermes-home (permissions/full disk).
Common situations: User hand-edited the shared hermes config into invalid syntax; env override map contains values that cannot be represented in the config format; leftover derived config in a recycled overlay owned by another user; env var interpolation producing invalid content.
Related errors
- Invalid desktop runtime config: ${field} must be a non-empty
- mint PAT: target API URL not set
- daemon profile is not resolved yet; token sync skipped
- runtime local skill import timed out
- Invalid desktop runtime config: ${field} must use http or ht
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/3c0f1b025c91ae12.
Report an issue: GitHub.