{"record":{"id":"34bffa771cd085d4","repo":"multica-ai/multica","slug":"update-workspace-repos-w","errorCode":null,"errorMessage":"update workspace repos: %w","messagePattern":"update workspace repos: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/multica/cmd_repo.go","lineNumber":136,"sourceCode":"\t}\n\treturn urls, nil\n}\n\nfunc fetchRepoWorkspace(ctx context.Context, client *cli.APIClient, workspaceID string) (repoWorkspaceResponse, error) {\n\tvar ws repoWorkspaceResponse\n\tif err := client.GetJSON(ctx, \"/api/workspaces/\"+workspaceID, &ws); err != nil {\n\t\treturn repoWorkspaceResponse{}, fmt.Errorf(\"get workspace: %w\", err)\n\t}\n\tif ws.Repos == nil {\n\t\tws.Repos = []workspaceRepo{}\n\t}\n\treturn ws, nil\n}\n\nfunc patchWorkspaceRepos(ctx context.Context, client *cli.APIClient, workspaceID string, repos []workspaceRepo) (repoWorkspaceResponse, error) {\n\tvar ws repoWorkspaceResponse\n\tif err := client.PatchJSON(ctx, \"/api/workspaces/\"+workspaceID, map[string]any{\"repos\": repos}, &ws); err != nil {\n\t\treturn repoWorkspaceResponse{}, fmt.Errorf(\"update workspace repos: %w\", err)\n\t}\n\tif ws.Repos == nil {\n\t\tws.Repos = []workspaceRepo{}\n\t}\n\treturn ws, nil\n}\n\nfunc repoCommandClient(cmd *cobra.Command) (*cli.APIClient, string, error) {\n\tworkspaceID, err := requireWorkspaceID(cmd)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\tclient, err := newAPIClient(cmd)\n\tif err != nil {\n\t\treturn nil, \"\", err\n\t}\n\treturn client, workspaceID, nil\n}","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/multica/cmd_repo.go#L118-L154","documentation":"Returned by patchWorkspaceRepos when client.PatchJSON to PATCH /api/workspaces/{workspaceID} with {\"repos\": [...]} fails. It is the write-side counterpart of error 640: the CLI first GETs the workspace, mutates the repos slice, then PATCHes it back. Failure means the server rejected or never received the update, so the registry is left unchanged.","triggerScenarios":"Calling `multica repo add` or `multica repo remove` where the PATCH returns 401/403/404/422 (e.g. invalid repo payload, workspace deleted between GET and PATCH), the connection drops mid-request, or the server errors while persisting.","commonSituations":"Concurrent CLI or UI edits that delete or lock the workspace between the GET and PATCH; permissions changed after the initial fetch; server-side validation rejecting a repo entry (empty URL, duplicate); network blips during long-running scripts.","solutions":["Re-run the command: the GET-modify-PATCH flow is idempotent for add (duplicate URLs are de-duped) and for remove (error 643 reports what is already gone).","Check auth and workspace existence as for error 640 — the same token/base URL is used for the PATCH.","If a 422/validation error is wrapped, inspect the server response body (the APIClient usually includes status/body detail) and fix the offending repo entry.","Retry after transient network failures; if the workspace was deleted mid-flight, re-create or pick another workspace."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"ws, err := patchWorkspaceRepos(ctx, client, workspaceID, repos)\nfor attempt := 1; err != nil && attempt <= 3; attempt++ {\n\t// re-fetch to avoid clobbering concurrent edits, then re-apply\n\tws, err = fetchRepoWorkspace(ctx, client, workspaceID)\n\tif err != nil { break }\n\tws, err = patchWorkspaceRepos(ctx, client, workspaceID, repos)\n}","preventionTips":["Treat add/remove as idempotent: safe to re-run the whole command after failure.","Avoid concurrent repo edits from multiple agents on one workspace; serialize them.","Check server reachability once at script start to fail before mutating."],"tags":["go","cli","http","patch","workspace","idempotency"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}