remotion-dev/remotion · error · Error
Could not locate the muted attribute
Error message
Could not locate the muted attribute
What it means
In the split-video-from-audio codemod, getMutedSourceEdit finds an existing 'muted' attribute on the <Video> element to toggle/rewrite it. If the attribute node exists but has no source location (loc is null), the codemod cannot compute the text range to replace and throws.
Solutions
- Run the codemod once per parse; re-parse the file between successive transforms so attributes carry fresh loc.
- If you added the muted attribute programmatically, serialize and re-parse before invoking the split codemod.
- Verify the input is parsed via recast with full location info.
- Guard in your pipeline: check existingMuted.loc before calling and skip with a message if absent.
Example fix
// before: attribute added in-memory, no loc video.openingElement.attributes.push(j.mutedAttribute); runSplitCodemod(ast); // after: apply edit, reparse, then split const code = applyEditsAndPrint(); runSplitCodemod(parse(code));
Defensive patterns
Strategy: type-guard
Validate before calling
const muted = element.openingElement.attributes.find((a) => getAttributeName(a) === 'muted');
if (muted && !muted.loc) { throw new Error('muted attribute lacks loc'); } Type guard
const isLocatableAttribute = (a: t.JSXAttribute) => a.loc != null;
Try / catch
try {
const edit = getMutedSourceEdit({element, input, getAttributeName});
} catch (err) {
// re-parse the file and retry the codemod
} Prevention
- Re-parse source between chained codemods so attributes regain loc
- Do not push hand-built attributes onto the AST before calling this codemod
- Run each codemod once per parse; serialize and re-parse between runs
- Verify parser configuration records full source locations
When it happens
Trigger: Running the codemod on a Video element that already has muted where the attribute node lacks loc — e.g. the attribute was added by a previous in-memory transform, cloned without loc, or produced by a parser that did not record locations.
Common situations: Applying the split codemod twice in one session on the same AST; codemods generated attribute nodes; files parsed with location-stripping options.
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
- Could not locate the JSX element to move
- Could not locate the JSX reorder target
- Could not locate the video opening element
- Cannot duplicate a JSX element without a source location
AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18).
Data as JSON: /api/errors/3717689cbca6b0ee.
Report an issue: GitHub.
Appendix: source
Thrown at packages/studio-codemods/src/split-video-from-audio.ts:184
closingFragment: {type: 'JSXClosingFragment'},
children: [first, second],
});
const getMutedSourceEdit = ({
element,
input,
prettierConfigOverride,
}: {
element: JSXElement;
input: string;
prettierConfigOverride: Record<string, unknown> | null;
}): 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;View on GitHub (pinned to 46a3a6bf13)