{"record":{"id":"78ed77a9f27ee5fe","repo":"hcengineering/platform","slug":"cannot-pause-from-state-state","errorCode":null,"errorMessage":"Cannot pause from state: ${state}","messagePattern":"Cannot pause from state: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugins/recorder-resources/src/stores/recorder.ts","lineNumber":169,"sourceCode":"        throw new Error('No active recording')\n      }\n\n      updateStore({ state: 'stopping' })\n      stopElapsedTimer()\n\n      const result = await screenRecorder.stop()\n      updateStore({ state: 'stopped', result })\n\n      manager.cleanup()\n      composer.cleanup()\n\n      screenRecorder = null\n    },\n\n    async pause (): Promise<void> {\n      const { state } = get(store)\n      if (state !== 'recording') {\n        throw new Error(`Cannot pause from state: ${state}`)\n      }\n\n      if (screenRecorder === null) {\n        throw new Error('No active recording')\n      }\n\n      await screenRecorder.pause()\n      stopElapsedTimer()\n      updateStore({ state: 'paused' })\n    },\n\n    async resume (): Promise<void> {\n      const { state } = get(store)\n\n      if (state !== 'paused') {\n        throw new Error(`Cannot resume from state: ${state}`)\n      }\n","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/plugins/recorder-resources/src/stores/recorder.ts#L151-L187","documentation":"`pause()` is only legal while the recorder state is exactly 'recording'. This error is thrown when pause is requested from any other state ('idle', 'ready', 'paused', 'stopping', 'stopped'). Pausing an already-paused recorder is deliberately rejected, so callers must track the state rather than treating pause as idempotent.","triggerScenarios":"Calling `recorder.pause()` twice in a row (second call sees 'paused'); calling `pause()` before `start()` ('ready'/'idle'); calling `pause()` while `stop()` is in flight ('stopping'); calling `pause()` after the recording already ended.","commonSituations":"A pause button wired to a handler that doesn't check state (and isn't toggled to call `resume()` when paused); keyboard shortcuts (e.g. spacebar) firing pause repeatedly; automated flows that pause unconditionally before stopping.","solutions":["Read the store state first and only call `pause()` when `state === 'recording'`; call `resume()` when `state === 'paused'`.","Implement pause as a toggle: if paused, call `resume()` instead of `pause()`.","Disable the pause control unless `state === 'recording'`.","If a stop was requested, wait for it to finish ('stopping') before considering further pause actions."],"exampleFix":"// before\npauseButton.onclick = () => { void recorder.pause() }\n\n// after\npauseButton.onclick = () => {\n  const { state } = getStore(recorder)\n  if (state === 'recording') void recorder.pause()\n  else if (state === 'paused') void recorder.resume()\n}","handlingStrategy":"validation","validationCode":"const { state } = get(recorder)\nif (state === 'paused') { await recorder.resume(); return }\nif (state !== 'recording') return\nawait recorder.pause()","typeGuard":"function canPause(state: RecorderState): state is 'recording' {\n  return state === 'recording'\n}","tryCatchPattern":"try {\n  await recorder.pause()\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Cannot pause from state:')) {\n    // derive intended action (resume/no-op) from current store state\n  } else throw err\n}","preventionTips":["Implement pause as a state-driven toggle (pause when recording, resume when paused).","Bind keyboard shortcuts to the same toggle and check state first.","Disable pause UI unless `state === 'recording'`.","Don't call `pause()` while a stop is pending ('stopping')."],"tags":["state-machine","recorder","pause","invalid-state-transition"],"backgroundTag":"invalid-state-transition","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}