amruthpillai/reactive-resume · error · ORPCError
STYLESHEET_PARITY_FAILED
STYLESHEET_PARITY_FAILED
Error message
The converted stylesheet does not preserve the legacy PDF presentation.
What it means
During the 'activate' transition, after the stylesheet compiles successfully, the service runs dependencies.parity() to compare the candidate semantic stylesheet's PDF output against the legacy rendering for the given resume data. If any mismatches are found it throws STYLESHEET_PARITY_FAILED with the mismatch list in error.data. This prevents activating a stylesheet that visibly changes the resume.
Source
Thrown at packages/api/src/features/resume/stylesheet-service.ts:272
if (preflight.ok) next = { ...next, applied: input.source };
}
}
if (input.transition === "activate") {
const compiled = compile(snapshot, input.source);
diagnostics = [...compiled.diagnostics];
if (!compiled.program) {
throw validationError("The stylesheet cannot be activated because it is invalid.", compiled.diagnostics);
}
const parity = await dependencies.parity({
data: snapshot.data,
stylesheet: input.source,
resumeId: snapshot.id,
revision: snapshot.stylesheetRevision,
});
if (parity.mismatches.length > 0) {
throw new ORPCError("STYLESHEET_PARITY_FAILED", {
status: 400,
message: "The converted stylesheet does not preserve the legacy PDF presentation.",
data: { mismatches: parity.mismatches },
});
}
const preflight = await runPreflight(snapshot, input.source);
didPreflight = true;
activationPageCount = preflight.ok ? preflight.pageCount : null;
if (!preflight.ok) {
diagnostics = [...compiled.diagnostics, ...preflight.diagnostics, preflightDiagnostic(preflight)];
throw validationError("The stylesheet failed PDF preflight.", diagnostics);
}
diagnostics = [...compiled.diagnostics, ...preflight.diagnostics];
next = { mode: "semantic", source: input.source, applied: input.source };
}
View on GitHub (pinned to 3a5b12e2a4)
Solutions
- Inspect error.data.mismatches to see which elements differ.
- Adjust the stylesheet source to resolve each mismatch, then re-run activate.
- Iterate faster by running checkLegacyStylesheetParity locally before submitting activate.
- Acceptable mismatches are a product decision — there is no code-level bypass.
Defensive patterns
Strategy: try-catch
Validate before calling
import { checkLegacyStylesheetParity } from '...';
async function preflightParity(data, source) {
const { mismatches } = await checkLegacyStylesheetParity({ data, stylesheet: source, resumeId, revision });
if (mismatches.length) console.warn('Parity mismatches:', mismatches);
} Try / catch
try {
await stylesheetService.activate(input);
} catch (e) {
if (e.code === 'STYLESHEET_PARITY_FAILED') {
// e.data.mismatches lists the diverging elements; revise source and retry
} else throw e;
} Prevention
- Run checkLegacyStylesheetParity locally before submitting activate.
- Iterate on the stylesheet source until mismatches is empty.
- Treat parity as a hard gate — there is no skip flag.
When it happens
Trigger: Activating a semantic CSS stylesheet whose compiled output diverges from the legacy PDF — different layout, colors, fonts, or page breaks — for the given resume data.
Common situations: A hand-written or AI-generated stylesheet that is close but not pixel-equivalent, a parity-checker version bump tightening tolerances, or resume data using features the conversion doesn't fully cover.
Related errors
AI-assisted analysis of amruthpillai/reactive-resume@3a5b12e2a4 (2026-08-12).
Data as JSON: /api/errors/69cc2eb3ba189761.
Report an issue: GitHub.