remotion-dev/remotion · error · Error

restartStudio() is only available in the Studio

Error message

restartStudio() is only available in the Studio

What it means

restartStudio() restarts the Studio server via /api/restart-studio and only exists inside the Node-based Studio. The first guard requires getRemotionEnvironment().isStudio to be true; outside Studio (renders, the Player, plain React/Node apps) it throws immediately. Sibling guards also reject Browser Studio and read-only Studio.

Source

Thrown at packages/studio/src/api/restart-studio.ts:13

/**
 * @description Restarts the Remotion Studio.
 * @see [Documentation](https://www.remotion.dev/docs/studio/restart-studio)
 */

import type {RestartStudioResponse} from '@remotion/studio-shared';
import {getRemotionEnvironment} from 'remotion';
import {callApi} from '../components/call-api';
import {getBrowserStudioOperations} from '../helpers/browser-studio-operations';

export const restartStudio = (): Promise<RestartStudioResponse> => {
	if (!getRemotionEnvironment().isStudio) {
		throw new Error('restartStudio() is only available in the Studio');
	}

	if (getBrowserStudioOperations() !== null) {
		throw new Error('restartStudio() is not supported in Browser Studio');
	}

	if (window.remotion_isReadOnlyStudio) {
		throw new Error('restartStudio() is not available in read-only Studio');
	}

	return callApi('/api/restart-studio', {});
};

View on GitHub (pinned to 10db9de073)

Solutions

  1. Restrict restartStudio() to Studio-only UI (toolbar buttons rendered only within Studio).
  2. Guard with getRemotionEnvironment().isStudio before calling.
  3. Handle the sibling cases too: in Browser Studio and read-only Studio the call throws separate errors - skip or hide the restart action there.
  4. If you need a restart-like experience outside Studio, restart your own dev server process instead.

Example fix

// before
import {restartStudio} from '@remotion/studio';

export const onUpdate = () => restartStudio(); // throws outside Studio

// after
import {getRemotionEnvironment} from 'remotion';
import {restartStudio} from '@remotion/studio';

export const onUpdate = () => {
  if (!getRemotionEnvironment().isStudio) {
    return; // no-op outside Studio
  }
  return restartStudio();
};
Defensive patterns

Strategy: type-guard

Validate before calling

import {getRemotionEnvironment} from 'remotion';

if (!getRemotionEnvironment().isStudio) {
  // do not call restartStudio() here - it throws outside Studio
} else {
  await restartStudio();
}

Type guard

import {getRemotionEnvironment} from 'remotion';

export const canRestartStudio = (): boolean =>
  getRemotionEnvironment().isStudio;

Try / catch

try {
  await restartStudio();
} catch (err) {
  if (err.message.includes('only available in the Studio')) {
    // called outside Studio - no-op, there is no Studio server to restart
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Calling restartStudio() from code that also runs outside Studio - compositions, shared hooks, Node scripts - or from an embedded Player preview; e.g. an 'update and restart' button defined in a module imported by both Studio UI and render-time code.

Common situations: Update flows written in shared utility modules that execute in both Studio and non-Studio environments; code copied from Studio internals into a Player app.

Related errors


AI-assisted analysis of remotion-dev/remotion@10db9de073 (2026-08-22). Data as JSON: /api/errors/532a4bcf5e9e0d0b. Report an issue: GitHub.