amruthpillai/reactive-resume · error · ORPCError

NOT_FOUND

NOT_FOUND

Error message

NOT_FOUND

What it means

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.

Solutions

  1. Verify the resume id exists and is owned by the user (resumeService.getById) before invoking stylesheet ops.
  2. Handle 404 in the UI by refreshing the resume list or redirecting away.
  3. Clear cached stylesheet state when the resume is deleted.
Defensive patterns

Strategy: validation

Validate before calling

async function assertResumeExists(id, userId) {
  const r = await resumeService.getById({ id, userId }).catch(() => null);
  if (!r) throw new Error(`Resume ${id} not found for user`);
}

Try / catch

try {
  await stylesheetService.read({ id, userId });
} catch (e) {
  if (e.code === 'NOT_FOUND') { /* redirect / refresh resume list */ }
  else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: A stale resume id in the client after deletion, navigating from a cached link, or a user attempting to reach another user's resume.

Understand the failure class

Background: NOT_FOUND error code: why tRPC, Harbor, Nacos and other libraries return 404 "not found" errors for resources that may still exist — this error's family across 11 libraries.

Related errors


AI-assisted analysis of amruthpillai/reactive-resume@3a5b12e2a4 (2026-08-12). Data as JSON: /api/errors/284681da43ed9930. Report an issue: GitHub.

Appendix: source

Thrown at packages/api/src/features/resume/stylesheet-service.ts:382

const snapshotSelection = {
	id: schema.resume.id,
	userId: schema.resume.userId,
	data: schema.resume.data,
	isLocked: schema.resume.isLocked,
	stylesheetRevision: schema.resume.stylesheetRevision,
	renderDataVersion: schema.resume.renderDataVersion,
	updatedAt: schema.resume.updatedAt,
};

export function createDatabaseStylesheetService(options: DatabaseStylesheetServiceOptions = {}) {
	const database = options.database ?? db;
	const runner = options.runner;
	const readSnapshot = async (input: { id: string; userId: string }) => {
		const [snapshot] = await database
			.select(snapshotSelection)
			.from(schema.resume)
			.where(and(eq(schema.resume.id, input.id), eq(schema.resume.userId, input.userId)));
		if (!snapshot) throw new ORPCError("NOT_FOUND");
		return snapshot;
	};

	return createStylesheetService({
		readSnapshot,
		convertLegacy: convertLegacyStylesheet,
		compile: compileStylesheet,
		...(runner
			? {
					preflight: ({ data, stylesheet }: { data: ResumeData; stylesheet: StylesheetSource }) =>
						runner.run({
							data,
							template: data.metadata.template,
							stylesheet,
						}),
				}
			: {}),
		parity: checkLegacyStylesheetParity,

View on GitHub (pinned to 3a5b12e2a4)