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

  1. Ensure bundleDir is a string before calling deploySiteFromBundle (typeof check or schema validation).
  2. Provide a concrete default or assert the field is present when reading from env/config.
  3. 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

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


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/00c58c14938f74d2. Report an issue: GitHub.