hcengineering/platform · error

Cannot pause from state: ${state}

Error message

Cannot pause from state: ${state}

What it means

`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.

Source

Thrown at plugins/recorder-resources/src/stores/recorder.ts:169

        throw new Error('No active recording')
      }

      updateStore({ state: 'stopping' })
      stopElapsedTimer()

      const result = await screenRecorder.stop()
      updateStore({ state: 'stopped', result })

      manager.cleanup()
      composer.cleanup()

      screenRecorder = null
    },

    async pause (): Promise<void> {
      const { state } = get(store)
      if (state !== 'recording') {
        throw new Error(`Cannot pause from state: ${state}`)
      }

      if (screenRecorder === null) {
        throw new Error('No active recording')
      }

      await screenRecorder.pause()
      stopElapsedTimer()
      updateStore({ state: 'paused' })
    },

    async resume (): Promise<void> {
      const { state } = get(store)

      if (state !== 'paused') {
        throw new Error(`Cannot resume from state: ${state}`)
      }

View on GitHub (pinned to 63e28dc964)

Solutions

  1. Read the store state first and only call `pause()` when `state === 'recording'`; call `resume()` when `state === 'paused'`.
  2. Implement pause as a toggle: if paused, call `resume()` instead of `pause()`.
  3. Disable the pause control unless `state === 'recording'`.
  4. If a stop was requested, wait for it to finish ('stopping') before considering further pause actions.

Example fix

// before
pauseButton.onclick = () => { void recorder.pause() }

// after
pauseButton.onclick = () => {
  const { state } = getStore(recorder)
  if (state === 'recording') void recorder.pause()
  else if (state === 'paused') void recorder.resume()
}
Defensive patterns

Strategy: validation

Validate before calling

const { state } = get(recorder)
if (state === 'paused') { await recorder.resume(); return }
if (state !== 'recording') return
await recorder.pause()

Type guard

function canPause(state: RecorderState): state is 'recording' {
  return state === 'recording'
}

Try / catch

try {
  await recorder.pause()
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Cannot pause from state:')) {
    // derive intended action (resume/no-op) from current store state
  } else throw err
}

Prevention

When it happens

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

Common situations: 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.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29). Data as JSON: /api/errors/78ed77a9f27ee5fe. Report an issue: GitHub.