From f1ed8784ffe5331a6da90662975a2caf526c41c8 Mon Sep 17 00:00:00 2001 From: Hongming Wang Date: Thu, 30 Apr 2026 22:13:04 -0700 Subject: [PATCH] docs(2429): document 410 Gone for removed workspaces Follow-up C to molecule-core#2449 + #2451 (a2a-client) + molecule-mcp-claude-channel#22 (channel bridge): - runtime-mcp.mdx Troubleshooting: new section explaining the 410 startup-time error from `get_workspace_info`, contrasting it with the heartbeat-401 escalation (which is the steady-state cure), and documenting the `?include_removed=true` opt-in for audit tooling. - external-agents.mdx Lifecycle: expanded the `removed` status with a per-caller behavior table so operators know exactly what each surface (wheel heartbeat, MCP tool, channel bridge, raw curl) looks like for a removed workspace. Both pages link back to the underlying PR so the audit trail is single-click navigable from the docs. Co-Authored-By: Claude Opus 4.7 (1M context) --- content/docs/external-agents.mdx | 18 ++++++++++++++++++ content/docs/runtime-mcp.mdx | 22 ++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/content/docs/external-agents.mdx b/content/docs/external-agents.mdx index 1602bab..85e7b99 100644 --- a/content/docs/external-agents.mdx +++ b/content/docs/external-agents.mdx @@ -244,6 +244,24 @@ create (POST /workspaces) → online (register) → offline (heartbeat expires) - No auto-restart (agent manages its own process) - Paused external workspaces skip heartbeat monitoring +### `removed` status — 410 Gone (#2429) + +Once a workspace transitions to `removed`: + +- **Tokens are revoked immediately**, but the row stays in the DB for audit-trail purposes +- `GET /workspaces/:id` returns **410 Gone** with `{error: "workspace removed", id, removed_at, hint}` so callers fail fast at startup instead of after ~60s of heartbeat 401s +- `DELETE /workspaces/:id` is the canonical removal trigger +- Audit / admin tooling that intentionally wants the legacy 200 + body shape opts in via `GET /workspaces/:id?include_removed=true` + +| Caller behavior on a removed workspace | What you should see | +|---|---| +| Wheel heartbeat | Logs ERROR after 3 consecutive 401s with re-onboard text | +| `get_workspace_info` MCP tool | Returns `{"error": "removed", "id", "removed_at", "hint"}` | +| Channel bridge `getWorkspaceInfo` | Throws `Workspace was deleted on the platform...` | +| Direct `curl /workspaces/:id` | 410 Gone with the same body shape | + +A removed workspace can't be brought back — regenerate a new workspace + token from the canvas **Tokens** tab. + ## Security - Bearer token required on all authenticated endpoints diff --git a/content/docs/runtime-mcp.mdx b/content/docs/runtime-mcp.mdx index 7ec6d7d..ae4d510 100644 --- a/content/docs/runtime-mcp.mdx +++ b/content/docs/runtime-mcp.mdx @@ -272,6 +272,28 @@ Regenerate from the canvas **Tokens** tab — a deleted workspace can't be brought back; you'll get a new workspace + token pair. Update your MCP config and restart your runtime. +### `Workspace was deleted on the platform...` from `get_workspace_info` + +Since [#2429](https://github.com/Molecule-AI/molecule-core/pull/2449), +`GET /workspaces/:id` returns **410 Gone** (not 200 + `status:"removed"`) +when the workspace has been deleted. The MCP wheel's `get_workspace_info` +tool surfaces this as a tailored error message: + +``` +Workspace was deleted on the platform at . +Regenerate workspace + token from the canvas → Tokens tab. +``` + +This is the **startup-time** counterpart to the heartbeat-401 escalation +above. If you see it within seconds of starting your runtime (rather +than after ~60s of heartbeat failures), the workspace was already gone +when you connected — regenerate as instructed. + +Audit-trail tools that intentionally want to inspect a removed workspace's +metadata (admin dashboards, "show me deleted workspaces" tooling) can +opt back into the legacy 200 + body shape via +`GET /workspaces/?include_removed=true`. + ### `claude mcp list` shows the new config but tools still 401 `/mcp` reconnect re-spawns the **cached** MCP config from session