remotion-dev/remotion · error
Could not serialize the visual control value
Error message
Could not serialize the visual control value
What it means
applyVisualControl() rewrites the second argument of a visualControl() call in source. It serializes the codemod's new value via stringifyDefaultProps; when that serializer returns undefined (it cannot produce a printable value for the given props), the codemod aborts with this error instead of writing a broken replacement.
Solutions
- Check the change's newValueSerialized / newValueIsUndefined fields and supply a serializable props value
- Update @remotion/studio-shared and studio-codemods to matching versions
- Apply the value change manually in the source file instead of running the codemod
Example fix
// before: change = { id: 'my-control', newValueSerialized: '{}', enumPaths: [] }
// after: change = { id: 'my-control', newValueSerialized: '"#ff0000"', enumPaths: [] } Defensive patterns
Strategy: validation
Validate before calling
const props = JSON.parse(change.newValueSerialized);
if (props === undefined || props === null) throw new Error('Visual control change has no serializable value'); Type guard
const isSerializable = (v: unknown) => v !== undefined && (typeof v !== 'object' || v === null || Object.keys(v).length > 0);
Try / catch
try {
applyVisualControl({input, transformation});
} catch (e) {
if ((e as Error).message.includes('Could not serialize the visual control value')) {
// fall back to manual edit / re-generate codemod with a valid value
}
} Prevention
- Always set a concrete newValueSerialized string when newValueIsUndefined is false
- Keep @remotion/studio-shared and studio-codemods versions in sync
- Validate codemod JSON payloads before applying them
When it happens
Trigger: A transformation.change with newValueIsUndefined=false whose newValueSerialized parses (via JSON.parse) to a props object that stringifyDefaultProps cannot serialize (e.g. an unsupported or empty value shape).
Common situations: A Studio codemod payload produced by a newer Remotion version contains a new value kind the local serializer does not understand; manually crafted codemod JSON with an empty or malformed value.
Understand the failure class
Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.
Related errors
- Could not find as a reorder target
- Expected sequence prop update result
- New composition ID does not match installation target
- New composition source does not match installation target
- No changes were made to the file
AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18).
Data as JSON: /api/errors/b3115b685d11f6ad.
Report an issue: GitHub.
Appendix: source
Thrown at packages/studio-codemods/src/apply-visual-control.ts:83
const firstArgument = node.arguments[0];
const str = expectString(firstArgument);
const matchingChanges = transformation.changes.filter(
(candidate) => candidate.id === str,
);
const change = matchingChanges.at(-1);
if (!change) {
return this.traverse(path);
}
const serialized = change.newValueIsUndefined
? 'undefined'
: stringifyDefaultProps({
props: JSON.parse(change.newValueSerialized),
enumPaths: change.enumPaths,
});
if (serialized === undefined) {
throw new Error('Could not serialize the visual control value');
}
const secondArgument = node.arguments[1];
if (secondArgument) {
if (!secondArgument.loc) {
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(),View on GitHub (pinned to 46a3a6bf13)