{"record":{"id":"267d68a7cad30671","repo":"Budibase/budibase","slug":"invalid-plugin-url","errorCode":null,"errorMessage":"Invalid plugin URL.","messagePattern":"Invalid plugin URL\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/server/src/api/controllers/plugin/url.ts","lineNumber":12,"sourceCode":"import { downloadUnzipTarball } from \"./utils\"\nimport {\n  deleteFolderFileSystem,\n  getPluginMetadata,\n} from \"../../../utilities/fileSystem\"\n\nfunction parseTarGzUrl(url: string): URL {\n  let parsed: URL\n  try {\n    parsed = new URL(url)\n  } catch {\n    throw new Error(\"Invalid plugin URL.\")\n  }\n\n  if (parsed.protocol !== \"https:\") {\n    throw new Error(\"Plugin URL must use HTTPS.\")\n  }\n\n  if (!parsed.pathname.endsWith(\".tar.gz\")) {\n    throw new Error(\"Plugin must be compressed into a gzipped tarball.\")\n  }\n\n  return parsed\n}\n\nexport async function urlUpload(url: string, name = \"\", headers = {}) {\n  parseTarGzUrl(url)\n\n  const path = await downloadUnzipTarball(url, name, headers, {\n    followRedirects: false,","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/plugin/url.ts#L1-L30","documentation":"parseTarGzUrl throws this when the provided plugin URL cannot be parsed by the URL constructor, i.e. it is not an absolute, well-formed URL.","triggerScenarios":"urlUpload called with a missing, empty, relative ('plugins/foo.tar.gz'), or malformed URL (spaces, missing scheme).","commonSituations":"Users pasting a relative path instead of a full URL; copying URLs with stray whitespace or missing https:// prefix; form field left empty.","solutions":["Supply a fully qualified absolute URL including the scheme","Check for trailing spaces or invalid characters in the URL","URL-encode any spaces or special characters"],"exampleFix":"// before\nawait urlUpload('myserver.com/plugins/my-plugin.tar.gz')\n// after\nawait urlUpload('https://myserver.com/plugins/my-plugin.tar.gz')","handlingStrategy":"validation","validationCode":"let parsed: URL\ntry { parsed = new URL(url) } catch { throw new Error('Provide an absolute URL including scheme, e.g. https://...') }","typeGuard":"function isValidUrl(url: string): boolean {\n  try { new URL(url); return true } catch { return false }\n}","tryCatchPattern":"try {\n  await urlUpload(url)\n} catch (err) {\n  if (err.message === 'Invalid plugin URL.') {\n    // normalize/trim the URL and require an absolute form\n  }\n}","preventionTips":["Always include the scheme (https://) in plugin URLs","Trim whitespace before submitting URLs","Use isValidUrl() client-side before calling the API"],"tags":["validation","url","plugins"],"backgroundTag":"invalid-url-scheme","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}