{"record":{"id":"284681da43ed9930","repo":"amruthpillai/reactive-resume","slug":"not-found-284681","errorCode":"NOT_FOUND","errorMessage":"NOT_FOUND","messagePattern":"NOT_FOUND","errorType":"error_code","errorClass":"ORPCError","httpStatus":404,"severity":"error","filePath":"packages/api/src/features/resume/stylesheet-service.ts","lineNumber":382,"sourceCode":"const snapshotSelection = {\n\tid: schema.resume.id,\n\tuserId: schema.resume.userId,\n\tdata: schema.resume.data,\n\tisLocked: schema.resume.isLocked,\n\tstylesheetRevision: schema.resume.stylesheetRevision,\n\trenderDataVersion: schema.resume.renderDataVersion,\n\tupdatedAt: schema.resume.updatedAt,\n};\n\nexport function createDatabaseStylesheetService(options: DatabaseStylesheetServiceOptions = {}) {\n\tconst database = options.database ?? db;\n\tconst runner = options.runner;\n\tconst readSnapshot = async (input: { id: string; userId: string }) => {\n\t\tconst [snapshot] = await database\n\t\t\t.select(snapshotSelection)\n\t\t\t.from(schema.resume)\n\t\t\t.where(and(eq(schema.resume.id, input.id), eq(schema.resume.userId, input.userId)));\n\t\tif (!snapshot) throw new ORPCError(\"NOT_FOUND\");\n\t\treturn snapshot;\n\t};\n\n\treturn createStylesheetService({\n\t\treadSnapshot,\n\t\tconvertLegacy: convertLegacyStylesheet,\n\t\tcompile: compileStylesheet,\n\t\t...(runner\n\t\t\t? {\n\t\t\t\t\tpreflight: ({ data, stylesheet }: { data: ResumeData; stylesheet: StylesheetSource }) =>\n\t\t\t\t\t\trunner.run({\n\t\t\t\t\t\t\tdata,\n\t\t\t\t\t\t\ttemplate: data.metadata.template,\n\t\t\t\t\t\t\tstylesheet,\n\t\t\t\t\t\t}),\n\t\t\t\t}\n\t\t\t: {}),\n\t\tparity: checkLegacyStylesheetParity,","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/amruthpillai/reactive-resume/blob/3a5b12e2a40374a9571988701fcb75c5a1831c42/packages/api/src/features/resume/stylesheet-service.ts#L364-L400","documentation":"readSnapshot() in createDatabaseStylesheetService selects the resume row by (id, userId); if no row matches it throws NOT_FOUND. This is the existence and ownership check that gates every stylesheet read operation before any compile/preflight work begins.","triggerScenarios":"Calling any stylesheet service method (read state, edit source, activate, deactivate) for a resume id that does not exist or does not belong to the authenticated user.","commonSituations":"A stale resume id in the client after deletion, navigating from a cached link, or a user attempting to reach another user's resume.","solutions":["Verify the resume id exists and is owned by the user (resumeService.getById) before invoking stylesheet ops.","Handle 404 in the UI by refreshing the resume list or redirecting away.","Clear cached stylesheet state when the resume is deleted."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"async function assertResumeExists(id, userId) {\n  const r = await resumeService.getById({ id, userId }).catch(() => null);\n  if (!r) throw new Error(`Resume ${id} not found for user`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await stylesheetService.read({ id, userId });\n} catch (e) {\n  if (e.code === 'NOT_FOUND') { /* redirect / refresh resume list */ }\n  else throw e;\n}","preventionTips":["Verify resume existence and ownership before invoking stylesheet operations.","Clear cached resume ids after deletion.","Handle 404 gracefully in the UI by refreshing the resume list."],"tags":["resume","stylesheet","not-found","ownership"],"backgroundTag":null,"analyzedSha":"3a5b12e2a40374a9571988701fcb75c5a1831c42","analyzedAt":"2026-08-12T22:31:22.666Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}