{"record":{"id":"7eef1604e26504fb","repo":"remotion-dev/remotion","slug":"trimafter-prop-must-be-greater-than-trimbefore-pro","errorCode":null,"errorMessage":"trimAfter prop must be greater than trimBefore prop.","messagePattern":"trimAfter prop must be greater than trimBefore prop\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/validate-start-from-props.ts","lineNumber":87,"sourceCode":"\t\tif (typeof trimAfter !== 'number') {\n\t\t\tthrow new TypeError(\n\t\t\t\t`type of trimAfter prop must be a number, instead got type ${typeof trimAfter}.`,\n\t\t\t);\n\t\t}\n\n\t\tif (isNaN(trimAfter)) {\n\t\t\tthrow new TypeError('trimAfter prop can not be NaN.');\n\t\t}\n\n\t\tif (trimAfter <= 0) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`trimAfter must be a positive number, instead got ${trimAfter}.`,\n\t\t\t);\n\t\t}\n\t}\n\n\tif ((trimAfter as number) <= (trimBefore as number)) {\n\t\tthrow new TypeError('trimAfter prop must be greater than trimBefore prop.');\n\t}\n};\n\nexport const validateMediaTrimProps = ({\n\tstartFrom,\n\tendAt,\n\ttrimBefore,\n\ttrimAfter,\n}: {\n\tstartFrom: number | undefined;\n\tendAt: number | undefined;\n\ttrimBefore: number | undefined;\n\ttrimAfter: number | undefined;\n}) => {\n\t// Check for conflicting props\n\tif (typeof startFrom !== 'undefined' && typeof trimBefore !== 'undefined') {\n\t\tthrow new TypeError(\n\t\t\t'Cannot use both startFrom and trimBefore props. Use trimBefore instead as startFrom is deprecated.',","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/validate-start-from-props.ts#L69-L105","documentation":"validateTrimProps enforces that trimAfter must be strictly greater than trimBefore, otherwise the requested playback window is empty or inverted. This check runs after individual type/range checks so both values are known to be valid numbers.","triggerScenarios":"Passing both trimBefore and trimAfter where trimAfter <= trimBefore, e.g. trimBefore={100} trimAfter={50}, or computed values where the trim window inverts.","commonSituations":"Swapping trimBefore and trimAfter by mistake; computing both from a dynamic source where the ordering assumption breaks; off-by-one when the two values are derived from separate timestamps.","solutions":["Ensure trimAfter is strictly greater than trimBefore: trimBefore={50} trimAfter={200}.","If computing dynamically, assert order before rendering: trimAfter = Math.max(trimAfter, trimBefore + 1).","Swap the two values if they were reversed."],"exampleFix":"// before\n<Audio src={src} trimBefore={100} trimAfter={50} />\n// after\n<Audio src={src} trimBefore={50} trimAfter={100} />","handlingStrategy":"validation","validationCode":"if (\n  trimBefore !== undefined &&\n  trimAfter !== undefined &&\n  trimAfter <= trimBefore\n) {\n  throw new Error('trimAfter must be greater than trimBefore');\n}","typeGuard":"const isValidTrimWindow = (\n  trimBefore: unknown,\n  trimAfter: unknown,\n): boolean =>\n  typeof trimBefore === 'number' &&\n  typeof trimAfter === 'number' &&\n  Number.isFinite(trimBefore) &&\n  Number.isFinite(trimAfter) &&\n  trimAfter > trimBefore;","tryCatchPattern":null,"preventionTips":["When computing both values dynamically, assert trimAfter > trimBefore before rendering.","Derive trimAfter from trimBefore + duration to keep ordering invariant by construction.","Double-check argument order when passing both props."],"tags":["validation","props","trimming","range"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}