{"record":{"id":"4ac34807051f58d0","repo":"Budibase/budibase","slug":"failed-to-clear-project-assignments","errorCode":null,"errorMessage":"Failed to clear project assignments.","messagePattern":"Failed to clear project assignments\\.","errorType":"http","errorClass":"HTTPError","httpStatus":500,"severity":"critical","filePath":"packages/server/src/sdk/workspace/projects/crud.ts","lineNumber":227,"sourceCode":"  }\n\n  try {\n    const results = await db.bulkDocs(changedDocs)\n    const failures = results\n      .map((result, index) => ({ result, index }))\n      .filter(({ result }) => result.error)\n\n    if (failures.length) {\n      for (const { result, index } of results\n        .map((result, index) => ({ result, index }))\n        .filter(({ result }) => !result.error)) {\n        const original = originals[index]\n        rollbacks.push(async () => {\n          await db.put({ ...original, _rev: result.rev })\n        })\n      }\n      await rollbackAssignments(rollbacks)\n      throw new HTTPError(\"Failed to clear project assignments.\", 500)\n    }\n\n    for (const [index, result] of results.entries()) {\n      const original = originals[index]\n      rollbacks.push(async () => {\n        await db.put({ ...original, _rev: result.rev })\n      })\n    }\n  } catch (err) {\n    if (!(err instanceof HTTPError)) {\n      await rollbackAssignments(rollbacks)\n    }\n    throw err\n  }\n\n  return rollbacks\n}\n","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/sdk/workspace/projects/crud.ts#L209-L245","documentation":"Thrown by clearAssignments when a bulkDocs batch removing the project from assigned documents reports per-document failures. The successfully updated docs are rolled back and a 500 HTTPError is raised, so project deletion is aborted with assignment state restored.","triggerScenarios":"Deleting a project (remove -> clearAssignments) while some assigned docs cannot be written — concurrent edits producing _rev conflicts during bulkDocs, validation rejections, or DB write errors on individual docs in the batch.","commonSituations":"Users editing rows/datasources at the same moment an admin deletes the project; replication or sync processes holding newer revisions; CouchDB contention under load.","solutions":["Retry the project deletion once concurrent edits have settled — the rollback leaves state consistent","Re-fetch the assigned docs and ensure no stale _rev conflicts exist before deleting","Check server logs (the rollback failure detail is logged) to identify which docs failed and why","Reduce concurrent automation/replication activity during deletion, then retry"],"exampleFix":"// before\ndeleteProject(id) // fails while users edit assigned docs\n// after\ntry {\n  await sdk.projects.remove(id, rev)\n} catch (e) {\n  if (String(e.message).includes(\"Failed to clear project assignments\")) {\n    await new Promise(r => setTimeout(r, 1000)) // let concurrent writes settle\n    const fresh = await sdk.projects.get(id)\n    if (fresh) await sdk.projects.remove(id, fresh._rev!)\n  }\n}","handlingStrategy":"retry","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  await sdk.projects.remove(id, rev)\n} catch (e) {\n  if (String(e.message).includes(\"Failed to clear project assignments\") && attempts < 3) {\n    await new Promise(r => setTimeout(r, backoff))\n    const fresh = await sdk.projects.get(id)\n    if (fresh) await sdk.projects.remove(id, fresh._rev!)\n  }\n}","preventionTips":["Retry deletion with backoff; state is rolled back and remains consistent","Avoid deleting projects while automations/replication are writing to assigned docs","Check server logs to identify the specific docs that failed bulkDocs","Inform users to pause concurrent editing sessions during project deletion"],"tags":["http-500","bulk-write","conflict","concurrency","delete"],"backgroundTag":"bulk-doc-write-conflict","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}