{"record":{"id":"0d6ebd732eca376e","repo":"remotion-dev/remotion","slug":"should-not-have-rendered-this-modal","errorCode":null,"errorMessage":"should not have rendered this modal","messagePattern":"should not have rendered this modal","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/studio/src/components/RenderModal/RenderStatusModal.tsx","lineNumber":108,"sourceCode":"\t\t} else {\n\t\t\tremoveRenderJob(job).catch((err) => {\n\t\t\t\tshowNotification(`Could not remove job: ${err.message}`, 2000);\n\t\t\t});\n\t\t}\n\t}, [job, isClientJob, removeClientJob, setSelectedModal]);\n\n\tconst onClickOnCancel = useCallback(() => {\n\t\tif (isClientJob) {\n\t\t\tcancelClientJob(job.id);\n\t\t} else {\n\t\t\tcancelRenderJob(job).catch((err) => {\n\t\t\t\tshowNotification(`Could not cancel job: ${err.message}`, 2000);\n\t\t\t});\n\t\t}\n\t}, [job, isClientJob, cancelClientJob]);\n\n\tif (job.status === 'idle') {\n\t\tthrow new Error('should not have rendered this modal');\n\t}\n\n\tconst errorDetails =\n\t\tjob.status === 'failed'\n\t\t\t? job.error.stack?.split('\\n')[0].includes(job.error.message)\n\t\t\t\t? job.error.stack\n\t\t\t\t: [job.error.message, job.error.stack].filter(Boolean).join('\\n')\n\t\t\t: null;\n\n\treturn (\n\t\t<ModalContainer onOutsideClick={onQuit} onEscape={onQuit}>\n\t\t\t<ModalHeader title={`Render ${job.compositionId}`} />\n\t\t\t<div style={container}>\n\t\t\t\t{job.status === 'failed' ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t<p>The render failed because of the following error:</p>\n\t\t\t\t\t\t<div className={HORIZONTAL_SCROLLBAR_CLASSNAME} style={codeBlock}>\n\t\t\t\t\t\t\t{errorDetails}","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/remotion-dev/remotion/blob/a6a7485a9aeb04219510fbe4874f8941486424df/packages/studio/src/components/RenderModal/RenderStatusModal.tsx#L90-L126","documentation":"The RenderStatusModal in Remotion Studio displays the progress of a render job (client or server). It assumes it is only ever opened for a job that is actually running or finished. If it is somehow rendered while the job's status is still 'idle', it throws 'should not have rendered this modal' as an internal invariant assertion.","triggerScenarios":"Opening the render status modal while job.status === 'idle' — e.g. the modal is mounted before the job transitions to 'rendering', or the modal remains mounted after the job was reset to idle.","commonSituations":"A race where the modal opens before the render starts; cancelling/resetting a job while the modal is visible; Studio bugs after hot reload; custom extensions triggering the modal for a job that never started.","solutions":["Only open RenderStatusModal after confirming the job status is not 'idle' (check job.status in the parent component)","Reset/close the modal whenever a job is cancelled or reset to idle","Reproduce in the Studio and report as a bug to Remotion if triggered by normal UI flow — this is an internal invariant","Ensure no stale job object is passed (e.g. cached state after reload); re-fetch the current job before rendering"],"exampleFix":"// before\n<RenderStatusModal job={job} />\n// after\n{job.status !== 'idle' && <RenderStatusModal job={job} />}","handlingStrategy":"validation","validationCode":"if (job && job.status !== 'idle') {\n  setModalOpen(true);\n}","typeGuard":"const isRenderableJob = (j: Job): j is Job & {status: Exclude<Job['status'], 'idle'>} =>\n  j.status !== 'idle';","tryCatchPattern":"try {\n  openRenderStatusModal(job);\n} catch (err) {\n  if (err instanceof Error && err.message === 'should not have rendered this modal') {\n    // job was reset to idle; close the modal silently\n    setModalOpen(false);\n    return;\n  }\n  throw err;\n}","preventionTips":["Gate the modal on a non-idle job status","Close the modal whenever a job is cancelled or reset","Re-fetch job state before opening the modal instead of using cached objects","Treat this throw as a bug report signal for stock Studio flows"],"tags":["studio","invariant","state-race","remotion"],"backgroundTag":"invariant-violation","analyzedSha":"a6a7485a9aeb04219510fbe4874f8941486424df","analyzedAt":"2026-09-02T16:25:19.997Z","contentChangedAt":"2026-09-02T16:25:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}