{"record":{"id":"add03bf61930b117","repo":"remotion-dev/remotion","slug":"stored-public-file-name-has-no-project-storage","errorCode":null,"errorMessage":"Stored public file ${name} has no project storage","messagePattern":"Stored public file (.+?) has no project storage","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/browser-studio/src/browser-studio-project-controller.ts","lineNumber":255,"sourceCode":"\t\tcontents: VirtualProjectPublicFile,\n\t\tproject: VirtualProject,\n\t) => {\n\t\tconst existing = objectUrls.get(name);\n\t\tif (arePublicFileContentsEqual(existing?.contents, contents)) {\n\t\t\treturn existing!.url;\n\t\t}\n\n\t\tif (existing) {\n\t\t\tresolvedRevokeObjectUrl(existing.url);\n\t\t}\n\n\t\tconst blob = isStoredPublicFile(contents)\n\t\t\t? await getBrowserStudioStoredPublicFile({\n\t\t\t\t\tfile: contents,\n\t\t\t\t\tstorage:\n\t\t\t\t\t\tproject.publicFileStorage ??\n\t\t\t\t\t\t(() => {\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`Stored public file ${name} has no project storage`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})(),\n\t\t\t\t})\n\t\t\t: new Blob([\n\t\t\t\t\ttypeof contents === 'string' ? contents : contents.slice().buffer,\n\t\t\t\t]);\n\t\tconst url = resolvedCreateObjectUrl(blob);\n\t\tobjectUrls.set(name, {\n\t\t\tcontents:\n\t\t\t\ttypeof contents === 'string' || isStoredPublicFile(contents)\n\t\t\t\t\t? contents\n\t\t\t\t\t: contents.slice(),\n\t\t\turl,\n\t\t});\n\t\treturn url;\n\t};\n","sourceCodeStart":237,"sourceCodeEnd":273,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/browser-studio/src/browser-studio-project-controller.ts#L237-L273","documentation":"Thrown by getObjectUrl in @remotion/browser-studio's project controller when a public file's contents are a 'stored' marker (isStoredPublicFile — the file lives in external storage, referenced by id) but `project.publicFileStorage` is null, so there is no way to fetch the bytes and build the object URL. It means the project was constructed with stored public files but no storage adapter was wired in, an embedding-host configuration mistake rather than a runtime condition.","triggerScenarios":"Creating a project whose publicFiles contain stored-file entries while `publicFileStorage` is null/undefined; loading a persisted project archive with stored assets into a controller that was not given a storage implementation; storage adapter removed or renamed during an upgrade.","commonSituations":"Restoring a downloaded project (makeBrowserStudioProjectArchive) without re-registering the storage backend that served the original assets; version upgrade where publicFileStorage became a required parameter for stored assets; tests using serialized projects without a mock storage.","solutions":["Pass a `publicFileStorage` implementation when constructing the project/controller used by getObjectUrl","If assets should be inline, re-save the public files with inline contents instead of stored markers","On upgrade, check the changelog for publicFileStorage signature changes","Catch the error per-file and surface which file name lacks storage instead of failing the whole render"],"exampleFix":"// before\nconst project = {\n  ...restoredProject, // publicFiles contain stored-file entries\n  publicFileStorage: null,\n};\n\n// after\nconst project = {\n  ...restoredProject,\n  publicFileStorage: {\n    getFile: async (file) => myBackend.fetchAsset(file.storageId),\n    putFile: async (file, bytes) => myBackend.putAsset(file.storageId, bytes),\n  },\n};","handlingStrategy":"validation","validationCode":"const canServeStoredFiles = project.publicFileStorage !== null;\nconst hasStoredFiles = Object.values(project.publicFiles ?? {}).some(\n  (f) => typeof f === 'object' && f !== null && 'type' in f && (f as {type?: string}).type === 'stored-public-file',\n);\nif (hasStoredFiles && !canServeStoredFiles) {\n  throw new Error('Project contains stored public files but no publicFileStorage is configured');\n}","typeGuard":"const hasPublicFileStorage = (\n  project: VirtualProject,\n): project is VirtualProject & {publicFileStorage: NonNullable<VirtualProject['publicFileStorage']>} =>\n  project.publicFileStorage !== null;","tryCatchPattern":"try {\n  const url = await getObjectUrl(name, contents, project);\n} catch (error) {\n  if (error instanceof Error && error.message.includes('has no project storage')) {\n    // configuration bug: wire a publicFileStorage before rendering stored assets\n  }\n  throw error;\n}","preventionTips":["Always construct the project with a publicFileStorage adapter when assets are stored externally","After restoring project archives, assert storage is configured before first render","Add an integration test that loads a serialized project and renders a stored asset"],"tags":["storage","public-files","configuration","browser-studio"],"backgroundTag":"missing-storage-provider","analyzedSha":"b2f4e34732f3c6c222ea029413e22dc402218cd7","analyzedAt":"2026-08-22T21:45:17.748Z","contentChangedAt":"2026-08-22T21:45:17.748Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}