{"record":{"id":"7dc5ad229bccc32c","repo":"multica-ai/multica","slug":"unsupported-desktop-runtime-config-schemaversion","errorCode":null,"errorMessage":"Unsupported desktop runtime config schemaVersion: expected 1","messagePattern":"Unsupported desktop runtime config schemaVersion: expected 1","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/desktop/src/shared/runtime-config.ts","lineNumber":69,"sourceCode":"}\n\nexport function parseRuntimeConfig(raw: string): RuntimeConfig {\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(raw);\n  } catch (err) {\n    throw new Error(\n      `Invalid desktop runtime config JSON: ${err instanceof Error ? err.message : \"parse failed\"}`,\n    );\n  }\n\n  if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n    throw new Error(\"Invalid desktop runtime config: expected a JSON object\");\n  }\n\n  const obj = parsed as Record<string, unknown>;\n  if (obj.schemaVersion !== 1) {\n    throw new Error(\"Unsupported desktop runtime config schemaVersion: expected 1\");\n  }\n\n  const apiUrl = requiredString(obj.apiUrl, \"apiUrl\");\n  const appUrl = optionalString(obj.appUrl, \"appUrl\");\n  const wsUrl = optionalString(obj.wsUrl, \"wsUrl\");\n\n  const normalizedApiUrl = normalizeHttpUrl(apiUrl, \"apiUrl\");\n  return {\n    schemaVersion: 1,\n    apiUrl: normalizedApiUrl,\n    wsUrl: wsUrl ? normalizeWsUrl(wsUrl, \"wsUrl\") : deriveWsUrl(normalizedApiUrl),\n    appUrl: appUrl ? normalizeHttpUrl(appUrl, \"appUrl\") : deriveAppUrl(normalizedApiUrl),\n  };\n}\n\nexport function deriveWsUrl(apiUrl: string): string {\n  const url = new URL(apiUrl);\n  if (url.protocol === \"https:\") url.protocol = \"wss:\";","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/apps/desktop/src/shared/runtime-config.ts#L51-L87","documentation":"Wrap thrown by execenv.Prepare when prepareCursorMcpConfig fails for a 'cursor'-provider task. The daemon materializes managed MCP servers into a project-local Cursor config and sets up an isolated per-task CURSOR_DATA_DIR so only servers with approval entries in that data dir can load — preventing user-global MCP servers from leaking into managed runs. Any failure in materializing the config or the data-dir sidecar aborts Prepare.","triggerScenarios":"Prepare is called with params.Provider == \"cursor\" and prepareCursorMcpConfig returns an error — e.g. writing the project-local .cursor/mcp.json or the approval sidecar inside CURSOR_DATA_DIR fails, or reading CursorMcpAuthSource fails.","commonSituations":"Work directory not writable (checked-out repo owned by another user); malformed params.McpConfig entries that cannot be rendered into Cursor's mcp.json format; a missing or unreadable CursorMcpAuthSource when the config references it; disk-full conditions on the env-root.","solutions":["Read the wrapped error to identify whether the project-local mcp.json write or the CURSOR_DATA_DIR sidecar failed; verify write permissions on workDir and env-root.","Validate the managed MCP config entries (well-formed names, URLs, transports) before assigning them to the task.","Ensure the Cursor auth source path exists and is readable by the daemon when the managed config needs auth material.","Free disk space and retry task preparation."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if params.Provider == \"cursor\" {\n    if err := validateMcpConfig(params.McpConfig); err != nil {\n        return fmt.Errorf(\"invalid managed MCP config: %w\", err)\n    }\n    if err := checkWritable(workDir); err != nil {\n        return fmt.Errorf(\"work dir not writable for cursor mcp config: %w\", err)\n    }\n}","typeGuard":null,"tryCatchPattern":"env, err := execenv.Prepare(ctx, params)\nif err != nil && strings.Contains(err.Error(), \"prepare cursor mcp config\") {\n    // inspect wrapped error: mcp.json write vs data-dir sidecar; fix perms/config, re-dispatch\n}","preventionTips":["Schema-validate managed MCP entries at configuration time.","Guarantee the checked-out workDir is writable by the daemon user.","Version-pin the Cursor tooling so config format expectations stay stable."],"tags":["go","execenv","cursor","mcp","filesystem"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}