{"record":{"id":"6cffb38b1a72d775","repo":"Significant-Gravitas/AutoGPT","slug":"transfer-request-transfer-id-not-found","errorCode":null,"errorMessage":"Transfer request {transfer_id} not found","messagePattern":"Transfer request (.+?) not found","errorType":"exception","errorClass":"NotFoundError","httpStatus":404,"severity":"error","filePath":"autogpt_platform/backend/backend/api/features/transfers/db.py","lineNumber":88,"sourceCode":"        order={\"createdAt\": \"desc\"},\n    )\n    return [TransferResponse.from_db(t) for t in transfers]\n\n\nasync def approve_transfer(\n    transfer_id: str,\n    user_id: str,\n    org_id: str,\n) -> TransferResponse:\n    \"\"\"Approve a transfer from the source or target side.\n\n    - If user's active org is the source org, sets sourceApprovedByUserId.\n    - If user's active org is the target org, sets targetApprovedByUserId.\n    - Advances the status accordingly.\n    \"\"\"\n    tr = await prisma.transferrequest.find_unique(where={\"id\": transfer_id})\n    if tr is None:\n        raise NotFoundError(f\"Transfer request {transfer_id} not found\")\n\n    if tr.status in (\"COMPLETED\", \"REJECTED\"):\n        raise ValueError(f\"Cannot approve a transfer with status '{tr.status}'\")\n\n    update_data: dict = {}\n\n    if org_id == tr.sourceOrganizationId:\n        if tr.sourceApprovedByUserId is not None:\n            raise ValueError(\"Source organization has already approved this transfer\")\n        update_data[\"sourceApprovedByUserId\"] = user_id\n        if tr.targetApprovedByUserId is not None:\n            # Both sides approved — ready for execution (NOT completed yet)\n            update_data[\"status\"] = \"TARGET_APPROVED\"\n        else:\n            update_data[\"status\"] = \"SOURCE_APPROVED\"\n\n    elif org_id == tr.targetOrganizationId:\n        if tr.targetApprovedByUserId is not None:","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/transfers/db.py#L70-L106","documentation":"NotFoundError from approve_transfer_request() when prisma.transferrequest.find_unique(transfer_id) returns None: the transfer being approved does not exist (deleted, expired/cleaned up, wrong ID, or wrong environment). Distinct from the later ValueError branches that fire when the transfer exists but is in a terminal state.","triggerScenarios":"Calling approve on a transfer ID from a stale notification/email link after the request was cancelled or removed, a typo'd ID, or a transfer created in a different database/environment.","commonSituations":"Approver opens an old email after the initiator cancelled; two approvers acting and one flow deleting the request; test suites referencing transfers created in a prior run.","solutions":["Re-fetch the user's pending transfers and confirm the ID still exists before approving.","If the transfer was cancelled/completed and removed, discard the stale notification/link.","Verify environment alignment (client pointed at the API that owns the transfer record)."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"tr = await prisma.transferrequest.find_unique(where={\"id\": transfer_id})\ntransfer_approvable = tr is not None and tr.status not in (\"COMPLETED\", \"REJECTED\")","typeGuard":null,"tryCatchPattern":"try:\n    resp = await approve_transfer_request(transfer_id, user_id, org_id)\nexcept NotFoundError:\n    discard_stale_notification(transfer_id)\n    raise HTTPException(404, \"Transfer no longer exists\")","preventionTips":["Have approval UI act on freshly fetched pending-transfer lists.","Expire or withdraw notifications when a transfer is cancelled."],"tags":["transfers","not-found","backend"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}