different-ai/openwork · error
scope must be 'project' or 'global'
Error message
scope must be 'project' or 'global'
What it means
resolveOpencodeConfigPath only accepts scope values 'project' or 'global'; anything else falls into the final else and throws. This is an explicit argument validation to prevent silently resolving config in an unintended location.
Source
Thrown at apps/desktop/electron/main.mjs:1468
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) {
const chosenPath = await selectOpencodeConfigPath(resolveOpencodeConfigPath(scope, projectDir));
const exists = await pathExists(chosenPath);
return {
path: chosenPath,
exists,
content: exists ? await readFile(chosenPath, "utf8") : null,
};View on GitHub (pinned to 2b7df46e8a)
Solutions
- Change scope to exactly 'project' or 'global' (lowercase).
- If the call came from commands-style code using 'workspace', switch it to 'project' for config APIs.
- Validate/normalize the scope string at the call site before invoking.
- Use a union type or constant enum for scope in renderer code so invalid values fail at compile time.
Example fix
// before
await resolveOpencodeConfigPath("workspace", dir);
// after
await resolveOpencodeConfigPath("project", dir); Defensive patterns
Strategy: validation
Validate before calling
const VALID_CONFIG_SCOPES = ['project', 'global'];
if (!VALID_CONFIG_SCOPES.includes(scope)) {
throw new Error(`scope must be one of ${VALID_CONFIG_SCOPES.join(', ')}, got ${scope}`);
} Type guard
function isConfigScope(scope) {
return scope === 'project' || scope === 'global';
} Prevention
- Share scope constants between the config and commands APIs to avoid 'project' vs 'workspace' drift.
- Use union types or enums in renderer code so invalid scopes fail at compile time.
- Never build scope strings dynamically from unvalidated settings input.
When it happens
Trigger: Calling a config-path API with scope misspelled ('Project', 'workspace', 'user'), undefined/null scope, or a scope value carried over from the commands API which uses 'workspace' instead of 'project'.
Common situations: Copy-pasting code between the commands API (scope 'workspace'|'global') and the config API (scope 'project'|'global'), typos in string literals, or dynamic scope values derived from unvalidated settings.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- scope must be 'workspace' or 'global'
- t("providers.provider_id_required")
- projectDir is required
- 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/046be3c58be3eb65.
Report an issue: GitHub.