remotion-dev/remotion · error · Error

Could not locate the video opening element

Error message

Could not locate the video opening element

What it means

getMutedSourceEdit, when no existing 'muted' attribute is found, needs the <Video> element's openingElement span to append a new muted attribute. It throws when the openingElement AST node has no source location, since the insertion offset cannot be computed.

Solutions

  1. Ensure the target element comes from the recast parse of real source code, not from hand-built AST nodes.
  2. If the element was transformed earlier, re-parse the printed source and re-locate the Video element before running this codemod.
  3. Preserve loc on cloned elements (copy openingElement.loc).
  4. Catch the error in your pipeline and skip the file with a warning rather than aborting the whole batch.

Example fix

// before: synthesized element without loc
const el = j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier('Video'), []), ...);
getMutedSourceEdit({element: el, input});
// after: use the parsed element
const el = findVideoElement(parse(input));
getMutedSourceEdit({element: el, input});
Defensive patterns

Strategy: type-guard

Validate before calling

if (!element.openingElement.loc) {
  throw new Error('Video opening element lacks loc; use a parsed node');
}

Type guard

const hasOpeningLoc = (el: t.JSXElement) => el.openingElement.loc != null;

Try / catch

try {
  const edit = getMutedSourceEdit({element, input, getAttributeName});
} catch (err) {
  // locate the Video element in a fresh parse and retry
}

Prevention

When it happens

Trigger: Calling the codemod with a JSXElement whose openingElement.loc is null — the element was synthesized in memory, cloned without loc, or the source was parsed without location recording.

Common situations: Generated Video elements passed into the split transform; chained codemods where an earlier step rebuilt the element node; custom tooling constructing AST nodes by hand.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18). Data as JSON: /api/errors/99b876d08f4cae8d. Report an issue: GitHub.

Appendix: source

Thrown at packages/studio-codemods/src/split-video-from-audio.ts:196

}): SourceEdit => {
	const existingMuted = element.openingElement.attributes.find(
		(attribute) => getAttributeName(attribute) === 'muted',
	);
	if (existingMuted) {
		if (!existingMuted.loc) {
			throw new Error('Could not locate the muted attribute');
		}

		return {
			start: recastLocToOffset(input, existingMuted.loc.start),
			end: recastLocToOffset(input, existingMuted.loc.end),
			replacement: 'muted',
		};
	}

	const {openingElement} = element;
	if (!openingElement.loc) {
		throw new Error('Could not locate the video opening element');
	}

	const openingStart = recastLocToOffset(input, openingElement.loc.start);
	const openingEnd = recastLocToOffset(input, openingElement.loc.end);
	const closingStart = openingEnd - (openingElement.selfClosing ? 2 : 1);
	const lineStart = input.lastIndexOf('\n', closingStart - 1) + 1;
	const beforeClosing = input.slice(lineStart, closingStart);

	if (lineStart > openingStart && /^[\t ]*$/.test(beforeClosing)) {
		const lastAttribute = openingElement.attributes.at(-1);
		const attributeIndent = lastAttribute?.loc
			? getLineIndent({
					input,
					offset: recastLocToOffset(input, lastAttribute.loc.start),
				})
			: `${getLineIndent({input, offset: openingStart})}${getIndentationUnit(
					input,
					prettierConfigOverride,

View on GitHub (pinned to 46a3a6bf13)