remotion-dev/remotion · error

Could not locate the visual control identifier

Error message

Could not locate the visual control identifier

What it means

When a visualControl() call has no second argument, the codemod appends a new value right after the first (identifier) argument. If that first argument node has no .loc, its insertion offset cannot be computed, so it throws this error.

Solutions

  1. Re-parse the original file and run the codemod on freshly parsed source
  2. Persist the inserted call to disk and re-run the codemod so recast assigns locations
  3. Add the value argument manually in the editor

Example fix

null
Defensive patterns

Strategy: try-catch

Validate before calling

const firstArgLocated = (node: any) => node.arguments[0] && node.arguments[0].loc !== undefined;

Type guard

const hasLoc = (n: {loc?: unknown}): n is {loc: NonNullable<unknown>} => n.loc != null;

Try / catch

try {
  applyVisualControl({input, transformation});
} catch (e) {
  if ((e as Error).message.includes('Could not locate the visual control identifier')) {
    // re-parse original source and retry, or add the value manually
  }
}

Prevention

When it happens

Trigger: Visiting a visualControl(id) call (single argument) whose first argument node lacks loc — usually because the call expression was synthesized by a previous codemod or generated AST rather than parsed from original source.

Common situations: Codemod pipelines where a visualControl call was inserted programmatically into the AST before applyVisualControl runs.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18). Data as JSON: /api/errors/bfcd81e71efa2b82. Report an issue: GitHub.

Appendix: source

Thrown at packages/studio-codemods/src/apply-visual-control.ts:107

					throw new Error('Could not locate the visual control value');
				}

				const start = recastLocToOffset(input, secondArgument.loc.start);
				const end = recastLocToOffset(input, secondArgument.loc.end);
				const lineStart = input.lastIndexOf('\n', start - 1) + 1;
				edits.push({
					start,
					end,
					replacement: formatSerializedValue({
						input,
						linePrefix: input.slice(lineStart, start),
						previousValue: input.slice(start, end).trim(),
						serialized,
					}),
				});
			} else {
				if (!firstArgument.loc) {
					throw new Error('Could not locate the visual control identifier');
				}

				const offset = recastLocToOffset(input, firstArgument.loc.end);
				const lineStart = input.lastIndexOf('\n', offset - 1) + 1;
				edits.push({
					start: offset,
					end: offset,
					replacement: `, ${formatSerializedValue({
						input,
						linePrefix: `${input.slice(lineStart, offset)}, `,
						previousValue: null,
						serialized,
					})}`,
				});
			}

			for (const matchingChange of matchingChanges) {
				changesMade.push({

View on GitHub (pinned to 46a3a6bf13)