sinelaw/fresh · error
workspace has no agent process to stop
Error message
workspace has no agent process to stop
What it means
requireEligible guards the single-workspace lifecycle verbs against ineligibility: for the "stop" action it throws this error when the workspace has no agent process to stop (bulkEligible('stop', id) is false). The picker disables such buttons; programmatic callers get an explicit reason instead of a silent no-op.
Solutions
- Check eligibility before stopping (e.g. verify the workspace has a running agent) or skip ineligible targets
- Handle the already-stopped case as success in your script logic
- Re-resolve the workspace; if it was archived, unarchive it first before lifecycle verbs
Example fix
// before
api.stopWorkspace(id);
// after
if (api.getWorkspace(id)?.hasRunningAgent) {
api.stopWorkspace(id);
} Defensive patterns
Strategy: validation
Validate before calling
const stoppable = (ws) => ws && ws.state === "running" && ws.hasRunningAgent; if (stoppable(api.getWorkspace(id))) api.stopWorkspace(id);
Type guard
function hasStoppableAgent(s) {
return s != null && s.hasRunningAgent === true && s.archived !== true;
} Try / catch
try {
api.stopWorkspace(id);
} catch (e) {
if (String(e).includes("no agent process to stop")) {
// already stopped: treat as success
} else throw e;
} Prevention
- Check the workspace's agent state before calling stop
- Deduplicate stop requests so a second click can't race the first
- Skip archived or pending workspaces in batch stop scripts
- Treat 'no agent process' as an idempotent-success case in automation
When it happens
Trigger: Calling apiStopWorkspace(target) for a workspace whose session has no running agent process — already stopped, archived, or a placeholder session that never spawned a process.
Common situations: Double-clicking Stop so the second call races the first; scripting stop across a workspace list containing archived entries; stopping a workspace created but whose agent never launched.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- workspace is still being created and cannot be
- workspace cannot be
- no such folder
- folder name must not be empty
- no such folder
AI-assisted analysis of sinelaw/fresh@67894ca546 (2026-09-13).
Data as JSON: /api/errors/96f7187a2316d816.
Report an issue: GitHub.
Appendix: source
Thrown at crates/fresh-editor/plugins/orchestrator.ts:10675
refreshOpenDialog();
return true;
}
function apiDeleteFolder(folderId: string): boolean {
if (!folderById(folderId)) return false;
// `deleteFolder` reparents the subtree one level up, so nothing inside is
// lost — same as the dock's "Delete Folder".
deleteFolder(folderId);
refreshDockTree();
return true;
}
/// Shared guard for the three lifecycle verbs: the picker disables a button
/// it cannot honour, and a caller deserves the reason rather than a no-op.
function requireEligible(s: AgentSession, action: BulkAction): void {
if (bulkEligible(action, s.id)) return;
if (action === "stop") {
throw new Error("workspace has no agent process to stop");
}
throw new Error(`workspace cannot be ${action === "archive" ? "archived" : "deleted"}`);
}
function apiStopWorkspace(target: string | number): boolean {
const s = resolveWorkspace(target);
if (!s) return false;
requireEligible(s, "stop");
// Same batch runner as the picker's confirmed Stop, over one id.
if (runStopBatch([s.id]) === 0) throw new Error("stop failed");
refreshOpenDialog();
return true;
}
/// Archive / delete over a single workspace, through the same batch runner
/// the picker's confirmed action uses — so the cross-machine manifest sync,
/// and anything added to that path later, applies to a scripted archive too.
async function runLifecycle(View on GitHub (pinned to 67894ca546)