{"record":{"id":"3717689cbca6b0ee","repo":"remotion-dev/remotion","slug":"could-not-locate-the-muted-attribute","errorCode":null,"errorMessage":"Could not locate the muted attribute","messagePattern":"Could not locate the muted attribute","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/studio-codemods/src/split-video-from-audio.ts","lineNumber":184,"sourceCode":"\tclosingFragment: {type: 'JSXClosingFragment'},\n\tchildren: [first, second],\n});\n\nconst getMutedSourceEdit = ({\n\telement,\n\tinput,\n\tprettierConfigOverride,\n}: {\n\telement: JSXElement;\n\tinput: string;\n\tprettierConfigOverride: Record<string, unknown> | null;\n}): SourceEdit => {\n\tconst existingMuted = element.openingElement.attributes.find(\n\t\t(attribute) => getAttributeName(attribute) === 'muted',\n\t);\n\tif (existingMuted) {\n\t\tif (!existingMuted.loc) {\n\t\t\tthrow new Error('Could not locate the muted attribute');\n\t\t}\n\n\t\treturn {\n\t\t\tstart: recastLocToOffset(input, existingMuted.loc.start),\n\t\t\tend: recastLocToOffset(input, existingMuted.loc.end),\n\t\t\treplacement: 'muted',\n\t\t};\n\t}\n\n\tconst {openingElement} = element;\n\tif (!openingElement.loc) {\n\t\tthrow new Error('Could not locate the video opening element');\n\t}\n\n\tconst openingStart = recastLocToOffset(input, openingElement.loc.start);\n\tconst openingEnd = recastLocToOffset(input, openingElement.loc.end);\n\tconst closingStart = openingEnd - (openingElement.selfClosing ? 2 : 1);\n\tconst lineStart = input.lastIndexOf('\\n', closingStart - 1) + 1;","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio-codemods/src/split-video-from-audio.ts#L166-L202","documentation":"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.","triggerScenarios":"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.","commonSituations":"Applying the split codemod twice in one session on the same AST; codemods generated attribute nodes; files parsed with location-stripping options.","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."],"exampleFix":"// before: attribute added in-memory, no loc\nvideo.openingElement.attributes.push(j.mutedAttribute);\nrunSplitCodemod(ast);\n// after: apply edit, reparse, then split\nconst code = applyEditsAndPrint();\nrunSplitCodemod(parse(code));","handlingStrategy":"type-guard","validationCode":"const muted = element.openingElement.attributes.find((a) => getAttributeName(a) === 'muted');\nif (muted && !muted.loc) { throw new Error('muted attribute lacks loc'); }","typeGuard":"const isLocatableAttribute = (a: t.JSXAttribute) => a.loc != null;","tryCatchPattern":"try {\n  const edit = getMutedSourceEdit({element, input, getAttributeName});\n} catch (err) {\n  // re-parse the file and retry the codemod\n}","preventionTips":["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"],"tags":["codemod","jsx","attribute","missing-loc"],"backgroundTag":"resource-not-found","analyzedSha":"46a3a6bf13ca367376ff18bbb06dae2e87e0d068","analyzedAt":"2026-09-18T00:12:20.256Z","contentChangedAt":"2026-09-18T00:12:20.256Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}