different-ai/openwork · error
projectDir is required
Error message
projectDir is required
What it means
resolveOpencodeConfigPath computes candidate opencode.json/opencode.jsonc paths for a given scope. For scope 'project', the candidates live under the project directory, so a non-empty projectDir is mandatory. When projectDir is missing, empty, or whitespace-only, the function throws 'projectDir is required' instead of guessing a directory.
Source
Thrown at apps/desktop/electron/main.mjs:1461
}
const openworkServer = assertOpenworkServerReady(await runtimeManager.openworkServerInfo());
return { ok: true, skipped: false, engine, openworkServer, workspaceId: bootWorkspace.id ?? null };
}
function ensureRuntimeBootstrap() {
if (!runtimeBootstrapPromise) {
runtimeBootstrapPromise = bootRuntimeForSelectedWorkspace().catch((error) => ({
ok: false,
error: error instanceof Error ? error.message : String(error),
}));
}
return runtimeBootstrapPromise;
}
function resolveOpencodeConfigPath(scope, projectDir) {
if (scope === "project") {
if (!String(projectDir ?? "").trim()) {
throw new Error("projectDir is required");
}
return workspaceOpencodeConfigCandidates(projectDir);
} else if (scope === "global") {
const root = globalOpencodeRoot();
return [path.join(root, "opencode.jsonc"), path.join(root, "opencode.json")];
} else {
throw new Error("scope must be 'project' or 'global'");
}
}
async function selectOpencodeConfigPath(candidates) {
for (const candidate of candidates) {
if (await pathExists(candidate)) return candidate;
}
return candidates[0];
}
async function readOpencodeConfig(scope, projectDir) {View on GitHub (pinned to 2b7df46e8a)
Solutions
- Pass a valid, non-empty absolute projectDir when calling with scope 'project'.
- Ensure a workspace/project is selected in the UI before invoking project-scoped config operations.
- Guard the caller: resolve the current workspace directory first and reject early if it is empty.
- If you truly want user-level config, use scope 'global' instead, which needs no projectDir.
Example fix
// before
await resolveOpencodeConfigPath("project");
// after
await resolveOpencodeConfigPath("project", workspace.dir); Defensive patterns
Strategy: validation
Validate before calling
if (scope === 'project' && (typeof projectDir !== 'string' || projectDir.trim() === '')) {
throw new Error('select a workspace before reading project config');
} Type guard
function hasProjectDir(dir) {
return typeof dir === 'string' && dir.trim().length > 0;
} Prevention
- Always resolve the active workspace path before project-scoped API calls.
- Use scope 'global' when no project context is intended.
- Type the scope/projectDir parameters in a shared IPC contract module.
- Render project-config UI only after a workspace is open.
When it happens
Trigger: Any IPC/renderer call that resolves config paths with scope='project' (e.g. reading/editing project opencode config) while passing projectDir as undefined, null, empty string, or a whitespace-only string.
Common situations: Renderer invoked a config command before a workspace was selected, a workspace object lost its path field, or an API refactor renamed the parameter so the value no longer reaches projectDir.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- t("providers.provider_id_required")
- scope must be 'project' or 'global'
- scope must be 'workspace' or 'global'
- name is required
- Agent context diagnostics timeout must be between 1 ms and 3
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/b8ddcdf9ede204c8.
Report an issue: GitHub.