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
- Ensure the attribute value is a static string literal: change <Video src={videoSrc} /> to <Video src="video.mp4" /> before running the codemod.
- Handle the expression case in your codemod: check attribute.value.type and only call this helper for StringLiteral (or expression-wrapped StringLiteral) values.
- If nodes are synthesized, run recast's parse/print cycle first so locs are populated, or set loc manually.
- 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
- Only pass attributes with static string values into source-edit helpers
- Check for JSXExpressionContainer wrappers and inspect the inner expression type
- Never hand-build attribute nodes for these helpers; use parsed nodes
- Skip dynamic props ({variable}) with a warning instead of failing
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
- Could not locate the folder insertion target
- Could not locate the muted attribute
- Cannot duplicate a JSX element without a source location
- Cannot duplicate JSX element with no parent
- Cannot split a JSX sequence without a source location
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('&', '&')
.replaceAll('"', '"')
.replaceAll("'", ''')
.replaceAll('<', '<') +
quote
: recast.prettyPrint(recast.types.builders.stringLiteral(newValue), {
quote: quote === "'" ? 'single' : 'double',
}).code;
View on GitHub (pinned to 46a3a6bf13)