{"record":{"id":"b2c1b3b3c4548d3e","repo":"remotion-dev/remotion","slug":"unsupported-protocol","errorCode":null,"errorMessage":"Unsupported protocol","messagePattern":"Unsupported protocol","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/studio-server/src/preview-server/studio-protocol/handle-element-library.ts","lineNumber":92,"sourceCode":"\t}\n\n\tconst parsedRequest =\n\t\tStudioProtocolInternals.parseStudioProtocolAddElementLibraryRequest(body);\n\tif (parsedRequest === null) {\n\t\twriteStudioProtocolError({\n\t\t\tcode: 'unsupported-protocol',\n\t\t\tmessage: 'Invalid Remotion Studio Protocol request.',\n\t\t\tresponse,\n\t\t\tstatus: 400,\n\t\t});\n\t\treturn;\n\t}\n\n\tlet normalizedUrl: string;\n\ttry {\n\t\tconst parsedUrl = new URL(parsedRequest.url);\n\t\tif (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n\t\t\tthrow new Error('Unsupported protocol');\n\t\t}\n\n\t\tnormalizedUrl = parsedUrl.href;\n\t} catch {\n\t\twriteStudioProtocolError({\n\t\t\tcode: 'invalid-url',\n\t\t\tmessage: 'The Element catalog URL must be an absolute HTTP or HTTPS URL.',\n\t\t\tresponse,\n\t\t\tstatus: 400,\n\t\t});\n\t\treturn;\n\t}\n\n\tconst displayName = parsedRequest.displayName?.trim() ?? null;\n\tif (displayName === '') {\n\t\twriteStudioProtocolError({\n\t\t\tcode: 'invalid-display-name',\n\t\t\tmessage: 'The Element catalog display name must not be empty.',","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/remotion-dev/remotion/blob/a6a7485a9aeb04219510fbe4874f8941486424df/packages/studio-server/src/preview-server/studio-protocol/handle-element-library.ts#L74-L110","documentation":"Remotion Studio's element-library protocol handler accepts a URL supplied by the client, parses it, and only forwards requests whose protocol is http: or https:. Any other scheme (file:, ftp:, data:, chrome:, etc.) is rejected with this error and converted into an 'invalid-url' studio protocol error response. This is a deliberate security guard to stop the Studio server from being used as a proxy to arbitrary protocols or local files.","triggerScenarios":"Calling the studio element-library endpoint with a URL whose scheme is not http/https, e.g. 'file:///home/user/icons.json', 'ftp://host/lib', or a URL string that fails URL parsing entirely; also a misconfigured element library source in studio config that points at a non-http location.","commonSituations":"Developers pointing the element library at a local file path instead of a local HTTP server; copying a data: or blob: URL from the browser; typos like 'htt://localhost:3000' that make URL parsing fail and fall into the same catch block.","solutions":["Serve the element library over HTTP(S): run a local server (npx serve, python -m http.server) and use 'http://localhost:PORT/lib.json' instead of a file: path","Fix the protocol typo or scheme so the URL starts with 'http://' or 'https://'","Check the studio config/CLI flag supplying the element-library URL and correct it","If the resource is local, proxy it through the Remotion Studio public/ folder or an existing dev server"],"exampleFix":"// before\nfetch('file:///home/me/library.json')\n// after\nfetch('http://localhost:8080/library.json')","handlingStrategy":"validation","validationCode":"function isHttpUrl(url: string): boolean {\n  try {\n    const u = new URL(url);\n    return u.protocol === 'http:' || u.protocol === 'https:';\n  } catch {\n    return false;\n  }\n}\nif (!isHttpUrl(libraryUrl)) throw new Error(`Element library URL must be http(s): ${libraryUrl}`);","typeGuard":"function isHttpUrl(url: string): url is `http://${string}` | `https://${string}` {\n  try {\n    const u = new URL(url);\n    return u.protocol === 'http:' || u.protocol === 'https:';\n  } catch {\n    return false;\n  }\n}","tryCatchPattern":"try {\n  await requestLibrary(url);\n} catch (err) {\n  if (err instanceof Error && (err.message === 'Unsupported protocol' || isInvalidUrlProtocolError(err))) {\n    console.error('Use an http:// or https:// URL, not ' + new URL(url).protocol);\n  } else throw err;\n}","preventionTips":["Always serve element libraries over a local or remote HTTP(S) server, never file: paths","Lint studio config for element-library URLs and assert the scheme at startup","For local assets, place them in the studio public/ folder instead of filesystem paths","Validate URLs with new URL() in your own tooling before handing them to the Studio server"],"tags":["url","validation","studio","protocol"],"backgroundTag":"unsupported-url-protocol","analyzedSha":"a6a7485a9aeb04219510fbe4874f8941486424df","analyzedAt":"2026-09-02T16:25:19.997Z","contentChangedAt":"2026-09-02T16:25:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}