{"record":{"id":"5382e964942eb51c","repo":"remotion-dev/remotion","slug":"the-filename-must-be-a-string-but-you-passed-a","errorCode":null,"errorMessage":"The \"filename\" must be a string, but you passed a value of type ${typeof filename}","messagePattern":"The \"filename\" must be a string, but you passed a value of type (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/validation/validate-artifact.ts","lineNumber":5,"sourceCode":"import type {TRenderAsset} from '../CompositionManager';\n\nexport const validateArtifactFilename = (filename: unknown) => {\n\tif (typeof filename !== 'string') {\n\t\tthrow new TypeError(\n\t\t\t`The \"filename\" must be a string, but you passed a value of type ${typeof filename}`,\n\t\t);\n\t}\n\n\tif (filename.trim() === '') {\n\t\tthrow new Error('The `filename` must not be empty');\n\t}\n\n\tif (!filename.match(/^([0-9a-zA-Z-!_.*'()/:&$@=;+,?]+)/g)) {\n\t\tthrow new Error(\n\t\t\t'The `filename` must match \"/^([0-9a-zA-Z-!_.*\\'()/:&$@=;+,?]+)/g\". Use forward slashes only, even on Windows.',\n\t\t);\n\t}\n};\n\nconst validateContent = (content: unknown) => {\n\tif (typeof content !== 'string' && !(content instanceof Uint8Array)) {\n\t\tthrow new TypeError(","sourceCodeStart":1,"sourceCodeEnd":23,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/validation/validate-artifact.ts#L1-L23","documentation":"When you register a render artifact (a custom output file emitted alongside the render via the artifacts API), the `filename` field must be a string so it can be written to the output directory and matched against the asset manifest. validateArtifactFilename rejects non-string filenames before they reach the filesystem layer.","triggerScenarios":"Registering an artifact with a non-string filename, e.g. {filename: 123, content: '...'} or {filename: {path: 'x.txt'}, content: '...'}, via registerRenderAsset or the artifacts registration API consumed by validateRenderAsset.","commonSituations":"Constructing the filename dynamically from a number without String(); spreading an untyped API response into the artifact object; passing a path object instead of a string.","solutions":["Pass filename as a string literal: {filename: 'output.txt', content: '...'}.","If the value is computed, coerce explicitly: {filename: String(name), content: '...'}.","If the value is a path object, extract its string form first (e.g. path.join(...) or obj.toString())."],"exampleFix":"// before\nregisterRenderAsset({type: 'artifact', filename: 123, content: 'data'});\n// after\nregisterRenderAsset({type: 'artifact', filename: 'output-123.txt', content: 'data'});","handlingStrategy":"type-guard","validationCode":"if (typeof filename !== 'string') {\n  throw new Error(`filename must be string, got ${typeof filename}`);\n}","typeGuard":"const isFilenameString = (v: unknown): v is string =>\n  typeof v === 'string';","tryCatchPattern":null,"preventionTips":["Type the artifact object with a `filename: string` field so the compiler enforces it.","Coerce computed names with String() before registering the artifact.","Do not spread untyped API responses into artifact registration; map fields explicitly."],"tags":["validation","artifacts","rendering","filename","typeerror"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}