different-ai/openwork · warning · Error
Select a workspace to inspect runtime config.
Error message
Select a workspace to inspect runtime config.
What it means
getRuntimeConfigStatus in the settings route requires both an initialized openworkClient and a selectedWorkspaceId; canInspectRuntimeConfig gates the UI on the same condition. If the getter is invoked despite either being missing, it throws to prevent calling getRuntimeConfigStatus with an undefined workspace id.
Solutions
- Select a workspace in Settings before inspecting runtime config.
- Reconnect the server so openworkClient is initialized, then retry.
- Guard the panel behind canInspectRuntimeConfig so the getter is only called when a client and workspace exist.
Example fix
// before
getRuntimeConfigStatus={async () => {
if (!openworkClient || !selectedWorkspaceId) {
throw new Error("Select a workspace to inspect runtime config.");
}
return openworkClient.getRuntimeConfigStatus(selectedWorkspaceId);
}}
// after
getRuntimeConfigStatus={async () => {
if (!openworkClient) await reconnectServer();
if (!selectedWorkspaceId) { toast("Select a workspace to inspect runtime config."); return null; }
return openworkClient.getRuntimeConfigStatus(selectedWorkspaceId);
}} Defensive patterns
Strategy: type-guard
Validate before calling
const inspectable = Boolean(openworkClient && selectedWorkspaceId); if (!inspectable) return null; // render picker/empty state instead of calling the getter
Type guard
function runtimeConfigReady(c: unknown, id: string | null | undefined)
: c is { getRuntimeConfigStatus: (id: string) => Promise<RuntimeConfigStatus> } {
return typeof c === "object" && c !== null && typeof id === "string" && id.length > 0
&& "getRuntimeConfigStatus" in c;
} Try / catch
try {
const status = await getRuntimeConfigStatus();
} catch (e) {
if (e instanceof Error && e.message.includes("Select a workspace")) {
setInspectorState("no-workspace");
} else throw e;
} Prevention
- Keep canInspectRuntimeConfig as the single gate and honor it in the UI.
- Never invoke getRuntimeConfigStatus with an empty workspace id.
- Reset inspector state when workspace selection changes.
- Re-create openworkClient on reconnect and re-render dependents.
When it happens
Trigger: Invoking the runtime-config inspector with no workspace selected (selectedWorkspaceId null/empty) or before the OpenWork client has been created (server not connected).
Common situations: Opening the runtime-config panel before choosing a workspace; a workspace deselect racing the panel open; server disconnect nulling openworkClient while the panel stays mounted.
Related errors
- Agent diagnostics require a connected workspace.
- app.error_compact_empty
- Cannot create a task without a selected workspace.
- Select an organization before managing connections.
- settings.environment.apply_no_local_workspace
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/f8136257383c9cb2.
Report an issue: GitHub.
Appendix: source
Thrown at apps/app/src/react-app/shell/settings-route.tsx:2612
/>
);
case "advanced":
return (
<AdvancedView
key={runtimeWorkspaceId ?? selectedWorkspaceId}
busy={busy}
clientConnected={Boolean(opencodeClient)}
opencodeConnectStatus={null}
openworkServerStatus={openworkServerSnapshot.openworkServerStatus}
developerMode={developerMode}
toggleDeveloperMode={toggleDeveloperMode}
opencodeDevModeEnabled={false}
openDebugDeepLink={async () => ({ ok: false, message: "Debug deep links are not wired into the React settings route yet." })}
cloudMcpUrl={openworkCloudMcpUrl}
canInspectRuntimeConfig={Boolean(openworkClient && selectedWorkspaceId)}
getRuntimeConfigStatus={async () => {
if (!openworkClient || !selectedWorkspaceId) {
throw new Error("Select a workspace to inspect runtime config.");
}
return openworkClient.getRuntimeConfigStatus(selectedWorkspaceId);
}}
cloudMcpHealth={cloudMcpHealth}
refreshCloudMcpHealth={refreshCloudMcpHealth}
organizationServer={denSession}
/>
);
case "appearance":
return (
<AppearanceView
busy={busy}
themeMode={themeMode}
setThemeMode={setThemeModeState}
language={currentLocale() as Language}
setLanguage={setLocale}
hideTitlebar={hideTitlebar}
toggleHideTitlebar={() => setHideTitlebar((current) => !current)}View on GitHub (pinned to 2b7df46e8a)