different-ai/openwork · error

Failed to write .opencode/openwork.json

Error message

Failed to write .opencode/openwork.json

What it means

createExtensionsStore writes the workspace .opencode/openwork.json config via the desktop bridge (workspaceOpenworkWrite) for local desktop workspaces. When the bridge reports result.ok === false, the store throws, surfacing the bridge's stderr/stdout if present, else the generic message. It indicates the config file could not be persisted to disk.

Source

Thrown at apps/app/src/react-app/domains/settings/state/extensions-store.ts:549

      hasOpenworkTarget &&
      openworkSnapshot.openworkServerCapabilities?.config?.write !== false;

    if (canUseOpenworkServer && openworkClient && openworkWorkspaceId) {
      await openworkClient.patchConfig(openworkWorkspaceId, { openwork: config });
      return true;
    }

    if (hasOpenworkTarget) {
      return false;
    }

    if (isLocalWorkspace && isDesktopRuntime() && root) {
      const result = (await workspaceOpenworkWrite({
        workspacePath: root,
        config: config as never,
      })) as { ok: boolean; stderr?: string; stdout?: string };
      if (!result.ok) {
        throw new Error(result.stderr || result.stdout || "Failed to write .opencode/openwork.json");
      }
      return true;
    }

    return false;
  };

  const refreshPendingCloudPluginChanges = async (installedPlugins?: Record<string, CloudImportedPlugin>) => {
    try {
      const target = await resolveWorkspaceServerTarget();
      if (!target.openworkClient || !target.openworkWorkspaceId) {
        setStateField("pendingCloudPluginChanges", {});
        return;
      }
      const syncResult = await refreshDesktopCloudSync({
        openworkClient: target.openworkClient,
        workspaceId: target.openworkWorkspaceId,
      }).catch(() => null);

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Read result.stderr/stdout (the thrown error includes it) to see the underlying write failure and fix it (permissions, path).
  2. Check the workspace folder and .opencode directory are writable by the app user.
  3. Verify the workspace path still exists on disk; re-select the workspace if it moved.
  4. Retry the persistence action after resolving filesystem issues.

Example fix

// before
if (!result.ok) {
  throw new Error(result.stderr || result.stdout || "Failed to write .opencode/openwork.json");
}
// after
if (!result.ok) {
  const detail = result.stderr || result.stdout || "unknown bridge failure";
  toast.error(`Could not save extension config: ${detail}. Check that the workspace folder is writable.`);
  return false;
}
Defensive patterns

Strategy: try-catch

Validate before calling

const probe = await workspaceOpenworkWrite({ workspacePath: root, config: { __probe: true } });
if (!probe.ok) console.error("workspace config not writable:", probe.stderr);

Try / catch

try {
  await saveExtensionConfig(config);
} catch (err) {
  if (err.message.includes(".opencode/openwork.json")) toast.error(`Check workspace folder permissions: ${err.message}`);
  else throw err;
}

Prevention

When it happens

Trigger: Persisting extensions/marketplace/plugin config when workspaceOpenworkWrite resolves with { ok: false } — e.g. the workspace directory lacks .opencode write permission, the path is read-only, or the bridge spawn fails and reports no stderr/stdout.

Common situations: Workspace folder owned by another user or opened read-only; disk full; .opencode directory created with wrong permissions; antivirus or OS blocking file writes; bridge unable to locate the workspace path (moved/renamed folder).

Understand the failure class

Background: "Permission denied" / "Failed to write" file errors: why a library can't write its files to disk (EACCES, EPERM, ENOSPC) and how to fix them — this error's family across 43 libraries.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/0ec834e8f2ef5d5b. Report an issue: GitHub.