remotion-dev/remotion · error

The mediaParserController() was not yet used in a parseMedia

Error message

The mediaParserController() was not yet used in a parseMedia() call

What it means

Thrown by MediaParserController.getSeekingHints() when the controller has never been registered with a parseMedia() call. The controller only learns the seeking-hints resolver through an internal callback that parseMedia attaches (attachSeekingHintResolution); before that the resolver is null and the method refuses to run. It exists to give a clear message instead of a null-reference failure.

Source

Thrown at packages/media-parser/src/controller/media-parser-controller.ts:67

			const err = new MediaParserAbortError('Aborted');
			if (abortController.signal.reason) {
				err.cause = abortController.signal.reason;
			}

			throw err;
		}

		await pauseSignal.waitUntilResume();
	};

	let seekingHintResolution: (() => Promise<SeekingHints | null>) | null = null;
	let simulateSeekResolution:
		| ((seekInSeconds: number) => Promise<SeekResolution>)
		| null = null;

	const getSeekingHints = () => {
		if (!seekingHintResolution) {
			throw new Error(
				'The mediaParserController() was not yet used in a parseMedia() call',
			);
		}

		return seekingHintResolution();
	};

	const simulateSeek = (seekInSeconds: number) => {
		if (!simulateSeekResolution) {
			throw new Error(
				'The mediaParserController() was not yet used in a parseMedia() call',
			);
		}

		return simulateSeekResolution(seekInSeconds);
	};

	const attachSeekingHintResolution = (

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass the controller to parseMedia first: parseMedia({src, controller, fields}) and only call getSeekingHints() once parsing has started.
  2. Call getSeekingHints() from within an event listener (e.g. after the first sample or duration event) so registration is guaranteed.
  3. Create a fresh mediaParserController() for each independent parseMedia run; never share one across runs.

Example fix

// before
const controller = mediaParserController();
const hints = await controller.getSeekingHints();

// after
const controller = mediaParserController();
parseMedia({src: '/video.mp4', controller, fields: {duration: true}});
controller.addEventListener('tracks', () => {
  controller.getSeekingHints().then(hints => console.log(hints));
});
Defensive patterns

Strategy: validation

Validate before calling

const controller = mediaParserController();
let registered = false;
controller.addEventListener('tracks', () => { registered = true; });
parseMedia({src, controller, fields: {duration: true}});
// only call after parseMedia has started
if (registered) await controller.getSeekingHints();

Type guard

null

Try / catch

try { await controller.getSeekingHints(); } catch (e) { if (e.message.includes('not yet used')) { /* defer until parseMedia starts */ } else throw e; }

Prevention

When it happens

Trigger: Creating a controller via mediaParserController() and calling controller.getSeekingHints() before passing that controller into parseMedia({controller}). Also calling it after parseMedia has completed and been torn down without a fresh registration.

Common situations: Inspecting seeking hints for UI/seek-bar setup before kicking off the parse loop. Reusing a controller object across a re-render lifecycle where the previous parseMedia already finished. Forgetting to pass the controller option to parseMedia.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/9d696786307786d8. Report an issue: GitHub.