remotion-dev/remotion · error · Error

Could not locate the

Error message

Could not locate the "${attribute.name.name}" attribute

What it means

getJsxStringAttributeValueSourceEdit extracts the raw source text of a JSX attribute's string value so a codemod can replace it. It throws when the attribute's value is missing, is not a plain StringLiteral (after unwrapping a JSXExpressionContainer), or has no source location, so no precise source edit can be computed.

Solutions

  1. Ensure the attribute value is a static string literal: change <Video src={videoSrc} /> to <Video src="video.mp4" /> before running the codemod.
  2. Handle the expression case in your codemod: check attribute.value.type and only call this helper for StringLiteral (or expression-wrapped StringLiteral) values.
  3. If nodes are synthesized, run recast's parse/print cycle first so locs are populated, or set loc manually.
  4. Wrap the call in try/catch and skip/replace such attributes instead of failing the whole transform.

Example fix

// before
<Video src={myVideo} />
// after
<Video src="https://example.com/myVideo.mp4" />
Defensive patterns

Strategy: type-guard

Validate before calling

const v = attribute.value;
const literal = v && v.type === 'JSXExpressionContainer' ? v.expression : v;
if (!literal || literal.type !== 'StringLiteral' || !literal.loc) {
  throw new SkipAttributeError(attribute);
}

Type guard

const hasStringLiteral = (attr: t.JSXAttribute): attr is t.JSXAttribute & {value: t.StringLiteral & {loc: unknown}} => {
  const v = attr.value;
  const lit = v && v.type === 'JSXExpressionContainer' ? v.expression : v;
  return !!lit && lit.type === 'StringLiteral' && !!lit.loc;
};

Try / catch

try {
  const edit = getJsxStringAttributeValueSourceEdit({attribute, input, newValue});
} catch (err) {
  // attribute is dynamic or missing a literal; skip this edit
}

Prevention

When it happens

Trigger: Calling the function with an attribute whose value is a JSXExpressionContainer containing a non-string expression (e.g. {someVar}, {true}, {`template`}), an empty attribute (<Video src />), or an attribute synthesized by code that lacks a loc.

Common situations: Codemods run against hand-written JSX where props are bound to variables or template literals instead of static strings; AST nodes created programmatically during a previous transform step have no recast loc; whitespace-only or shorthand attributes.

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/a96b05bcba04b13b. Report an issue: GitHub.

Appendix: source

Thrown at packages/studio-codemods/src/source-edits.ts:38

export type ImportSnapshot = {
	declaration: ImportDeclaration;
	specifiers: NonNullable<ImportDeclaration['specifiers']>;
};

export const getJsxStringAttributeValueSourceEdit = ({
	attribute,
	input,
	newValue,
}: {
	attribute: JSXAttribute;
	input: string;
	newValue: string;
}): SourceEdit => {
	const {value} = attribute;
	const literal =
		value?.type === 'JSXExpressionContainer' ? value.expression : value;
	if (!literal?.loc || literal.type !== 'StringLiteral') {
		throw new Error(`Could not locate the "${attribute.name.name}" attribute`);
	}

	const start = recastLocToOffset(input, literal.loc.start);
	const end = recastLocToOffset(input, literal.loc.end);
	const quote = input[start] === "'" ? "'" : '"';
	const replacement =
		value?.type === 'StringLiteral'
			? quote +
				newValue
					.replaceAll('&', '&amp;')
					.replaceAll('"', '&quot;')
					.replaceAll("'", '&apos;')
					.replaceAll('<', '&lt;') +
				quote
			: recast.prettyPrint(recast.types.builders.stringLiteral(newValue), {
					quote: quote === "'" ? 'single' : 'double',
				}).code;

View on GitHub (pinned to 46a3a6bf13)