remotion-dev/remotion · error · Error

Could not locate the import to update

Error message

Could not locate the import to update

What it means

In getInsertImportSourceEdits, when some added specifiers are not ImportSpecifiers (e.g. ImportDefaultSpecifier or ImportNamespaceSpecifier), the whole import statement must be rewritten, which requires the statement's source location. It throws when statement.loc is missing, typically because the AST node was synthesized or loc data was not preserved.

Solutions

  1. Parse the source with recast (which records loc) and take the ImportDeclaration directly from that tree.
  2. If the import was created by your own code, serialize it with recast.print and re-parse before further edits.
  3. Avoid cloning import statements; keep original node references to preserve loc.
  4. Catch and fall back to appending a completely new import statement instead of rewriting the existing one.

Example fix

// before: mutated node without loc
addSpecifiers(mutatedStatement, specifiers);
// after
const ast = parse(input);
const stmt = ast.program.body.find(isImportDeclaration);
addSpecifiers(stmt, specifiers);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!statement.loc) {
  throw new Error('ImportDeclaration lacks loc; re-parse before rewriting');
}

Type guard

const isLocatableImport = (s: t.Node): s is t.ImportDeclaration & {loc: NonNullable<t.ImportDeclaration['loc']>} => s.type === 'ImportDeclaration' && s.loc != null;

Try / catch

try {
  const edits = getInsertImportSourceEdits({statement, input, addedSpecifiers});
} catch (err) {
  // fall back: emit a new import statement edit
}

Prevention

When it happens

Trigger: Adding a default import (e.g. `import React from 'react'` style additions) to an import statement node that has no loc — such as one produced by previous in-memory transforms, a cloned node, or a parse that discarded locations.

Common situations: Multi-step codemods that rewrite imports then add default specifiers; third-party transforms stripping loc; running the codemod on programmatically generated code.

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

Appendix: source

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

			const importPrefix = input.slice(importStart).match(/^import\s+/)?.[0];
			if (!importPrefix) {
				throw new Error('Could not locate the import prefix to update');
			}

			const offset = importStart + importPrefix.length;
			edits.push({
				end: offset,
				replacement: `${addedSpecifiers.map(renderImportSpecifier).join(', ')}, `,
				start: offset,
			});
			continue;
		}

		if (
			addedSpecifiers.some((specifier) => specifier.type !== 'ImportSpecifier')
		) {
			if (!statement.loc) {
				throw new Error('Could not locate the import to update');
			}

			const fullImportStart = recastLocToOffset(input, statement.loc.start);
			const fullImportEnd = recastLocToOffset(input, statement.loc.end);
			const fullImport = input.slice(fullImportStart, fullImportEnd);
			edits.push({
				end: fullImportEnd,
				replacement: renderImportDeclaration({
					bracketSpacing: getImportBracketSpacing({
						declaration: statement,
						input,
						prettierConfigOverride,
					}),
					declaration: statement,
					quote: fullImport.includes('"') ? '"' : "'",
					semicolon: fullImport.trimEnd().endsWith(';') ? ';' : '',
				}),
				start: fullImportStart,

View on GitHub (pinned to 46a3a6bf13)