{"record":{"id":"00c58c14938f74d2","repo":"remotion-dev/remotion","slug":"the-bundledir-must-be-a-string-but-received-j","errorCode":null,"errorMessage":"The `bundleDir` must be a string, but received ${JSON.stringify(bundleDir)}.","messagePattern":"The `bundleDir` must be a string, but received (.+?)\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/lambda/src/shared/validate-bundle-dir.ts","lineNumber":47,"sourceCode":"\t\tif (entry.isSymbolicLink()) {\n\t\t\tif (fs.statSync(entryPath).isDirectory()) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`The bundle directory ${bundleDir} contains a symbolic link to a directory at ${path.relative(bundleDir, entryPath)}. Directory symbolic links are not supported by \\`deploySiteFromBundle()\\`.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.isDirectory()) {\n\t\t\tvalidateNoDirectorySymlinks(entryPath, bundleDir);\n\t\t}\n\t}\n};\n\nexport const validateBundleDir = (bundleDir: unknown): string => {\n\tif (typeof bundleDir !== 'string') {\n\t\tthrow new TypeError(\n\t\t\t`The \\`bundleDir\\` must be a string, but received ${JSON.stringify(bundleDir)}.`,\n\t\t);\n\t}\n\n\tconst resolvedBundleDir = path.resolve(bundleDir);\n\n\tif (!fs.existsSync(resolvedBundleDir)) {\n\t\tthrow new Error(\n\t\t\t`The bundle directory ${resolvedBundleDir} does not exist. Run \\`npx remotion bundle\\` or pass a valid \\`bundleDir\\`.`,\n\t\t);\n\t}\n\n\tif (!fs.statSync(resolvedBundleDir).isDirectory()) {\n\t\tthrow new Error(\n\t\t\t`The bundle path ${resolvedBundleDir} is not a directory. Pass the directory returned by \\`bundle()\\` or created by \\`npx remotion bundle\\`.`,\n\t\t);\n\t}\n","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/lambda/src/shared/validate-bundle-dir.ts#L29-L65","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ndeploySiteFromBundle({bucketName, region, bundleDir: process.env.BUNDLE_DIR})\n// after\nconst bundleDir = process.env.BUNDLE_DIR\nif (typeof bundleDir !== 'string') throw new Error('BUNDLE_DIR missing')\ndeploySiteFromBundle({bucketName, region, bundleDir})","handlingStrategy":"type-guard","validationCode":"if (typeof bundleDir !== 'string' || bundleDir.length === 0) {\n  throw new Error('bundleDir must be a non-empty string')\n}","typeGuard":"const isBundleDir = (v: unknown): v is string => typeof v === 'string' && v.trim().length > 0","tryCatchPattern":null,"preventionTips":["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."],"tags":["validation","typescript","configuration"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}