{"record":{"id":"80baae32f8d05138","repo":"lobehub/lobehub","slug":"not-found-80baae","errorCode":"NOT_FOUND","errorMessage":"Acceptance not found","messagePattern":"Acceptance not found","errorType":"error_code","errorClass":"TRPCError","httpStatus":404,"severity":"error","filePath":"apps/server/src/routers/lambda/acceptance.ts","lineNumber":62,"sourceCode":"        ctx.userId,\n        ctx.workspaceId ?? undefined,\n      ),\n    },\n  });\n});\n\n// Writes: workspace mode requires at least the member role (viewers are\n// read-only); personal mode passes through unrestricted.\nconst acceptanceWriteProcedure = acceptanceProcedure.use(requireWorkspaceRoleWhenScoped('member'));\n\nconst resolveAcceptance = async (\n  ctx: { acceptanceService: AcceptanceService },\n  id: string,\n): Promise<AcceptanceItem> => {\n  const acceptance = await ctx.acceptanceService.acceptanceModel.findById(id);\n\n  if (!acceptance) {\n    throw new TRPCError({ code: 'NOT_FOUND', message: 'Acceptance not found' });\n  }\n\n  return acceptance;\n};\n\nexport const acceptanceRouter = router({\n  /**\n   * The user accepts the delivery — the terminal business event that closes\n   * the acceptance lifecycle. The verifier's verdict is a recommendation; this\n   * click is the event (a failed/uncertain round can still be accepted, which\n   * means the user knowingly takes it with its exceptions).\n   */\n  accept: acceptanceWriteProcedure\n    .input(z.object({ comment: z.string().max(2000).optional(), id: z.string() }))\n    .mutation(async ({ ctx, input }) => {\n      const acceptance = await resolveAcceptance(ctx, input.id);\n      assertWorkspaceRowManageable(ctx, acceptance.userId, 'acceptance');\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/lobehub/lobehub/blob/10f24d7ade75139093a9373b364f6bc91f3cd7db/apps/server/src/routers/lambda/acceptance.ts#L44-L80","documentation":"resolveAcceptance helper:findById returned no row for the given acceptance id. Every write procedure (accept, attachRun, saveChecklist, saveGoal, setVisibility, markRepairing, reject, rename, updateStatus, remove, addGroupFeedback, reviewChecks) routes through this resolver, so this is the canonical 'wrong id' failure across the acceptance API.","triggerScenarios":"Any acceptance mutation called with an id that does not exist in the caller's scope (the model is constructed with userId + workspaceId, so the row must match the caller's ownership/scope filter). Stale id after deletion, id from a different workspace, malformed id.","commonSituations":"Client cached an acceptance id across a delete; URL parameter typo; cross-workspace id leak; the model's scope filter excluded it because the caller is not the owner and is in a different workspace.","solutions":["Refresh the acceptance list (acceptance.list) and use a current id.","Verify the caller is the acceptance owner or a member of its workspace — the model is scope-filtered.","If migrating data, confirm the acceptance row was inserted and not rolled back."],"exampleFix":"// before\nawait trpc.acceptance.accept.mutate({ id: staleId }); // NOT_FOUND\n\n// after\nconst list = await trpc.acceptance.list.query();\nawait trpc.acceptance.accept.mutate({ id: list[0].id });","handlingStrategy":"validation","validationCode":"const acceptance = await ctx.acceptanceService.acceptanceModel.findById(id);\nif (!acceptance) throw new TRPCError({ code: 'NOT_FOUND', message: 'Acceptance not found' });","typeGuard":"const isAcceptanceItem = (x: unknown): x is AcceptanceItem =>\n  typeof x === 'object' && x !== null && typeof (x as any).id === 'string';","tryCatchPattern":"try {\n  await trpc.acceptance.accept.mutate({ id, comment });\n} catch (e) {\n  if (e.code === 'NOT_FOUND') refreshAcceptanceList();\n}","preventionTips":["Always resolve acceptance ids from acceptance.list, never from cached URLs.","Pass ids through the model scope filter (userId + workspaceId) so cross-workspace ids fail cleanly."],"tags":["acceptance","not-found","trpc","ownership","scope-filter"],"backgroundTag":null,"analyzedSha":"10f24d7ade75139093a9373b364f6bc91f3cd7db","analyzedAt":"2026-08-12T11:43:19.543Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}