different-ai/openwork · error · Error

workspace_inaccessible

workspace_inaccessible

Error message

Workspace path is not accessible: ${workspacePath}

What it means

prepareRuntimeWorkspaceRoot normalizes the project directory, mkdir -p's it, and optionally writes config; any failure is wrapped by workspaceInaccessibleError into code 'workspace_inaccessible' with the message 'Workspace path is not accessible: <path>'. The library throws it to fail fast when the workspace root cannot be created or prepared instead of booting a runtime on a broken path.

Source

Thrown at apps/desktop/electron/runtime.mjs:254

    workspacePath: { value: workspacePath, enumerable: true },
  });
  return error;
}

export async function prepareRuntimeWorkspaceRoot(projectDir, options = {}) {
  const rawProjectDir = String(projectDir ?? "").trim();
  try {
    const workspaceRoot = normalizeWorkspaceRootPath(rawProjectDir, {
      platform: options.platform ?? process.platform,
    });
    if (!workspaceRoot) throw new Error("projectDir is required");
    await (options.mkdirImpl ?? mkdir)(workspaceRoot, { recursive: true });
    if (typeof options.ensureConfig === "function") {
      await options.ensureConfig(workspaceRoot);
    }
    return workspaceRoot;
  } catch (error) {
    throw workspaceInaccessibleError(rawProjectDir, error);
  }
}

export function resolveOpenworkServerConfigPath(env = process.env) {
  return openworkServerConfigPath({ env });
}

export function seedWorkspacePathsForEmbeddedServer(workspacePaths, serverConfigExists) {
  return serverConfigExists ? [] : workspacePaths;
}

export function selectStickyOpenworkPortWorkspace(requestedWorkspacePaths = [], serverWorkspacePaths = []) {
  for (const value of [...requestedWorkspacePaths, ...serverWorkspacePaths]) {
    const workspacePath = String(value ?? "").trim();
    if (workspacePath) return workspacePath;
  }
  return "";
}

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Inspect error.cause for the underlying fs code (EACCES/EROFS/ENOENT/ENOSPC) and fix that condition.
  2. Verify the path exists, is a directory, and is writable by the app user (ls -ld, touch a test file).
  3. Fix ownership/permissions (chown/chmod) or move the workspace to a writable location.
  4. If a custom ensureConfig was injected, run it manually to see its failure.

Example fix

// before
const root = await prepareRuntimeWorkspaceRoot("/mnt/share/project"); // read-only mount
// after
import { access, constants } from "node:fs/promises";
try { await access("/mnt/share/project", constants.W_OK); } catch (e) { throw new Error("Fix workspace permissions/mount before boot: " + e.code); }
const root = await prepareRuntimeWorkspaceRoot("/mnt/share/project");
Defensive patterns

Strategy: validation

Validate before calling

import { stat, access, constants } from "node:fs/promises";
const s = await stat(projectDir).catch(() => null);
if (!s?.isDirectory()) throw new Error(`${projectDir} is not a directory`);
await access(projectDir, constants.W_OK); // throws EACCES before runtime boot

Type guard

async function isWritableWorkspaceDir(p) {
  try {
    const s = await stat(p);
    if (!s.isDirectory()) return false;
    await access(p, constants.W_OK);
    return true;
  } catch { return false; }
}

Try / catch

try {
  await prepareRuntimeWorkspaceRoot(projectDir);
} catch (e) {
  if (e?.code === "workspace_inaccessible") {
    console.error(`Workspace ${e.workspacePath} unusable: ${e.cause?.code ?? e.cause?.message}`);
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling prepareRuntimeWorkspaceRoot(projectDir) where normalizeWorkspaceRootPath rejects the path, mkdir fails (EACCES, EROFS, ENOSPC, path is a file), or the injected ensureConfig callback throws.

Common situations: Workspace pointing at a read-only mount or network share that is unmounted; parent directory owned by another user; passing a file path instead of a directory; disk quota exceeded; project dir on a drive that no longer exists.

Related errors


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