remotion-dev/remotion · error · TypeError
The `bundleDir` must be a string, but received ${JSON.string
Error message
The `bundleDir` must be a string, but received ${JSON.stringify(bundleDir)}. What it means
Thrown by validateBundleDir() (a TypeError) when the bundleDir argument is not a string. Because the public deploySiteFromBundle signature types bundleDir as string, this guard exists to catch callers that bypass TypeScript or pass undefined/null/objects at runtime.
Source
Thrown at packages/lambda/src/shared/validate-bundle-dir.ts:47
if (entry.isSymbolicLink()) {
if (fs.statSync(entryPath).isDirectory()) {
throw new Error(
`The bundle directory ${bundleDir} contains a symbolic link to a directory at ${path.relative(bundleDir, entryPath)}. Directory symbolic links are not supported by \`deploySiteFromBundle()\`.`,
);
}
continue;
}
if (entry.isDirectory()) {
validateNoDirectorySymlinks(entryPath, bundleDir);
}
}
};
export const validateBundleDir = (bundleDir: unknown): string => {
if (typeof bundleDir !== 'string') {
throw new TypeError(
`The \`bundleDir\` must be a string, but received ${JSON.stringify(bundleDir)}.`,
);
}
const resolvedBundleDir = path.resolve(bundleDir);
if (!fs.existsSync(resolvedBundleDir)) {
throw new Error(
`The bundle directory ${resolvedBundleDir} does not exist. Run \`npx remotion bundle\` or pass a valid \`bundleDir\`.`,
);
}
if (!fs.statSync(resolvedBundleDir).isDirectory()) {
throw new Error(
`The bundle path ${resolvedBundleDir} is not a directory. Pass the directory returned by \`bundle()\` or created by \`npx remotion bundle\`.`,
);
}
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Ensure bundleDir is a string before calling deploySiteFromBundle (typeof check or schema validation).
- Provide a concrete default or assert the field is present when reading from env/config.
- If using TypeScript, make sure the value actually flows as string and not Promise<string> | undefined.
Example fix
// before
deploySiteFromBundle({bucketName, region, bundleDir: process.env.BUNDLE_DIR})
// after
const bundleDir = process.env.BUNDLE_DIR
if (typeof bundleDir !== 'string') throw new Error('BUNDLE_DIR missing')
deploySiteFromBundle({bucketName, region, bundleDir}) Defensive patterns
Strategy: type-guard
Validate before calling
if (typeof bundleDir !== 'string' || bundleDir.length === 0) {
throw new Error('bundleDir must be a non-empty string')
} Type guard
const isBundleDir = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0
Prevention
- Read bundleDir from config with a schema validator (zod, etc.).
- Default env-sourced values with a concrete fallback string.
- Type the call site strictly so undefined cannot leak through.
When it happens
Trigger: Calling deploySiteFromBundle without a bundleDir, or passing a value from an untyped source (env var, JSON config) that is undefined, null, a number, or an object.
Common situations: Reading bundleDir from process.env without a fallback; passing the result of bundle() before awaiting it; spreading a config object that omits bundleDir; CLI/integration code that lost the field.
Related errors
- maxRetries must be a number, but is ${JSON.stringify(maxRetr
- "serveURL" parameter must be a string, but is ${JSON.stringi
- "serviceName" parameter must be a string, but is ${JSON.stri
- The 'siteName' argument must be a string if provided, but is
- Invalid runtime preference ${option}. Must be one of ${Lambd
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/00c58c14938f74d2.
Report an issue: GitHub.