{"record":{"id":"ff37d4c99fbe891d","repo":"remotion-dev/remotion","slug":"assetpath-must-be-a-non-empty-public-folder-path","errorCode":null,"errorMessage":"assetPath must be a non-empty public-folder path, or an asset must be selected in Studio.","messagePattern":"assetPath must be a non-empty public-folder path, or an asset must be selected in Studio\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/studio/src/components/WebMcp.tsx","lineNumber":184,"sourceCode":"\tassetPath,\n\tcurrentContent,\n\tstaticFiles,\n}: {\n\treadonly assetPath: unknown;\n\treadonly currentContent: {\n\t\treadonly asset?: string;\n\t\treadonly type: string;\n\t} | null;\n\treadonly staticFiles: readonly {readonly name: string}[];\n}) => {\n\tconst resolvedAssetPath =\n\t\tassetPath === undefined\n\t\t\t? currentContent?.type === 'asset'\n\t\t\t\t? (currentContent.asset ?? null)\n\t\t\t\t: null\n\t\t\t: assetPath;\n\tif (typeof resolvedAssetPath !== 'string' || resolvedAssetPath.length === 0) {\n\t\tthrow new Error(\n\t\t\t'assetPath must be a non-empty public-folder path, or an asset must be selected in Studio.',\n\t\t);\n\t}\n\n\tif (!staticFiles.some((file) => file.name === resolvedAssetPath)) {\n\t\tthrow new Error(`Asset ${resolvedAssetPath} was not found in public/.`);\n\t}\n\n\treturn resolvedAssetPath;\n};\n\nconst WebMcpSelectionSync: FC<{\n\treadonly currentSelectionRef: MutableRefObject<string | null>;\n\treadonly selectedSequenceRef: MutableRefObject<WebMcpSequence | null>;\n}> = ({currentSelectionRef, selectedSequenceRef}) => {\n\tconst {selectedItems} = useTimelineSelection();\n\tconst {sequences} = useContext(Internals.SequenceManager);\n\tconst {overrideIdToNodePathMappings} = useContext(","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio/src/components/WebMcp.tsx#L166-L202","documentation":"The WebMcp asset tool resolves the asset path from the explicit assetPath argument or the currently selected Studio content. If neither yields a non-empty string, it throws because it cannot determine which public-folder asset to operate on.","triggerScenarios":"Calling the WebMcp asset tool with assetPath omitted while no asset is selected in Studio, or passing assetPath: '' / non-string.","commonSituations":"MCP agent calls the tool without arguments expecting the selection to provide context; Studio opened without selecting an asset; a script sending an empty string path.","solutions":["Pass an explicit non-empty assetPath pointing at a file in public/ (e.g. 'audio/voice.mp3').","Select the desired asset in Remotion Studio before invoking the tool.","Double-check the argument spelling — assetPath, not src or path.","List static files first to pick a valid public-folder path."],"exampleFix":"// before\nawait tool.execute({}); // no selection\n// after\nawait tool.execute({assetPath: 'audio/voice.mp3'});","handlingStrategy":"type-guard","validationCode":"if (typeof assetPath !== 'string' || assetPath.length === 0) {\n  throw new Error('assetPath is required when no asset is selected.');\n}","typeGuard":"const hasAssetPath = (a: unknown): a is string =>\n  typeof a === 'string' && a.length > 0;","tryCatchPattern":"try {\n  const p = resolveAssetPath(input);\n} catch (e) {\n  if (e.message.includes('assetPath must be a non-empty')) {\n    return 'No asset selected — pass assetPath explicitly.';\n  }\n}","preventionTips":["Always pass assetPath explicitly from tooling.","Select an asset in Studio before invoking selection-less calls.","Validate non-empty string inputs before tool calls."],"tags":["mcp","validation","studio"],"backgroundTag":"missing-required-argument","analyzedSha":"46a3a6bf13ca367376ff18bbb06dae2e87e0d068","analyzedAt":"2026-09-09T13:27:51.281Z","contentChangedAt":"2026-09-09T13:27:51.281Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}