{"record":{"id":"3d512cdda7fb130a","repo":"multica-ai/multica","slug":"remove-workspace-mcp-server-w","errorCode":null,"errorMessage":"remove workspace mcp server: %w","messagePattern":"remove workspace mcp server: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/multica/cmd_workspace.go","lineNumber":737,"sourceCode":"\twsID, err := resolveWorkspaceArg(cmd, args[1:])\n\tif err != nil {\n\t\treturn err\n\t}\n\tif wsID == \"\" {\n\t\treturn fmt.Errorf(\"workspace ID is required: pass an id/slug/prefix as argument or set MULTICA_WORKSPACE_ID\")\n\t}\n\n\tclient, err := newAPIClient(cmd)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tctx, cancel := cli.APIContext(context.Background())\n\tdefer cancel()\n\n\tpath := \"/api/workspaces/\" + wsID + \"/mcp-servers/\" + url.PathEscape(serverID)\n\tif err := client.DeleteJSON(ctx, path); err != nil {\n\t\treturn fmt.Errorf(\"remove workspace mcp server: %w\", err)\n\t}\n\n\tfmt.Fprintf(os.Stdout, \"removed MCP server %s\\n\", serverID)\n\treturn nil\n}\n\n// workspaceMcpServer is the CLI's half of the write-only boundary. Decoding\n// into named fields — rather than a map[string]any that gets re-encoded —\n// means a server that regressed to returning a stored entry, or a `url` /\n// `headers` inside one, cannot reach stdout through ANY output format. Fields\n// not declared here are dropped by encoding/json.\ntype workspaceMcpServer struct {\n\tID        string `json:\"id\"`\n\tName      string `json:\"name\"`\n\tTransport string `json:\"transport\"`\n\t// Only set on an agent's assignment list; nil in the workspace library.\n\tEnabled *bool `json:\"enabled,omitempty\"`\n}","sourceCodeStart":719,"sourceCodeEnd":755,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/multica/cmd_workspace.go#L719-L755","documentation":"Wrapped failure of the HTTP DELETE to /api/workspaces/{id}/mcp-servers/{serverId} (path-escaped) performed by `multica workspace mcp remove`. Chained causes: 404 when the server ID or workspace does not exist, 401/403 for auth/permission problems, or transport errors.","triggerScenarios":"Removing a server that was already deleted (double-run of a cleanup script), using an ID from another workspace, or the token lacking write permission.","commonSituations":"Idempotency-unaware cleanup scripts that re-run removals; stale IDs after re-adding a server; read-only member attempting removal.","solutions":["If the server is already gone, treat 404 as success in scripts (grep the wrapped message) or check existence with `mcp list` first","Re-list to get current IDs and re-run with a valid one","For 401/403, use a token with owner/admin rights on the workspace"],"exampleFix":"# before (script fails on second run)\nmultica workspace mcp remove 17 acme\n\n# after (tolerate already-removed)\nmultica workspace mcp list acme | grep -q '^17 ' && multica workspace mcp remove 17 acme || echo \"already removed\"","handlingStrategy":"try-catch","validationCode":"// check existence first to make removal idempotent\nservers, err := listServers(ctx, wsID)\nif err != nil {\n    return err\n}\nfound := false\nfor _, s := range servers {\n    if s.ID == serverID {\n        found = true\n    }\n}\nif !found {\n    return nil // already removed; nothing to do\n}","typeGuard":null,"tryCatchPattern":"err := client.DeleteJSON(ctx, path)\nif err != nil {\n    var httpErr *apiclient.HTTPError\n    if errors.As(err, &httpErr) && httpErr.StatusCode == 404 {\n        return nil // treat as already-removed for idempotent cleanup\n    }\n    return fmt.Errorf(\"remove workspace mcp server: %w\", err)\n}","preventionTips":["Make cleanup scripts idempotent: treat 404 on delete as success","List before delete when IDs may be stale","Use admin-scoped tokens for destructive MCP operations"],"tags":["cli","http","mcp","api-client","idempotency"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}