{"record":{"id":"a96b05bcba04b13b","repo":"remotion-dev/remotion","slug":"could-not-locate-the-attribute-name-name-attribute","errorCode":null,"errorMessage":"Could not locate the \"${attribute.name.name}\" attribute","messagePattern":"Could not locate the \"(.+?)\" attribute","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/studio-codemods/src/source-edits.ts","lineNumber":38,"sourceCode":"export type ImportSnapshot = {\n\tdeclaration: ImportDeclaration;\n\tspecifiers: NonNullable<ImportDeclaration['specifiers']>;\n};\n\nexport const getJsxStringAttributeValueSourceEdit = ({\n\tattribute,\n\tinput,\n\tnewValue,\n}: {\n\tattribute: JSXAttribute;\n\tinput: string;\n\tnewValue: string;\n}): SourceEdit => {\n\tconst {value} = attribute;\n\tconst literal =\n\t\tvalue?.type === 'JSXExpressionContainer' ? value.expression : value;\n\tif (!literal?.loc || literal.type !== 'StringLiteral') {\n\t\tthrow new Error(`Could not locate the \"${attribute.name.name}\" attribute`);\n\t}\n\n\tconst start = recastLocToOffset(input, literal.loc.start);\n\tconst end = recastLocToOffset(input, literal.loc.end);\n\tconst quote = input[start] === \"'\" ? \"'\" : '\"';\n\tconst replacement =\n\t\tvalue?.type === 'StringLiteral'\n\t\t\t? quote +\n\t\t\t\tnewValue\n\t\t\t\t\t.replaceAll('&', '&amp;')\n\t\t\t\t\t.replaceAll('\"', '&quot;')\n\t\t\t\t\t.replaceAll(\"'\", '&apos;')\n\t\t\t\t\t.replaceAll('<', '&lt;') +\n\t\t\t\tquote\n\t\t\t: recast.prettyPrint(recast.types.builders.stringLiteral(newValue), {\n\t\t\t\t\tquote: quote === \"'\" ? 'single' : 'double',\n\t\t\t\t}).code;\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio-codemods/src/source-edits.ts#L20-L56","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\n<Video src={myVideo} />\n// after\n<Video src=\"https://example.com/myVideo.mp4\" />","handlingStrategy":"type-guard","validationCode":"const v = attribute.value;\nconst literal = v && v.type === 'JSXExpressionContainer' ? v.expression : v;\nif (!literal || literal.type !== 'StringLiteral' || !literal.loc) {\n  throw new SkipAttributeError(attribute);\n}","typeGuard":"const hasStringLiteral = (attr: t.JSXAttribute): attr is t.JSXAttribute & {value: t.StringLiteral & {loc: unknown}} => {\n  const v = attr.value;\n  const lit = v && v.type === 'JSXExpressionContainer' ? v.expression : v;\n  return !!lit && lit.type === 'StringLiteral' && !!lit.loc;\n};","tryCatchPattern":"try {\n  const edit = getJsxStringAttributeValueSourceEdit({attribute, input, newValue});\n} catch (err) {\n  // attribute is dynamic or missing a literal; skip this edit\n}","preventionTips":["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"],"tags":["codemod","jsx","source-edit","attribute"],"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"}