{"record":{"id":"0d8ae1bf11d99115","repo":"Budibase/budibase","slug":"invalid-import-url","errorCode":null,"errorMessage":"Invalid import url","messagePattern":"Invalid import url","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/query/import/index.ts","lineNumber":79,"sourceCode":"    if (existingKey) {\n      continue\n    }\n    target[headerName] = target[headerName] ?? \"\"\n  }\n}\n\nconst stringToHashKey = (input: string) =>\n  crypto.createHash(\"sha512\").update(JSON.stringify(input)).digest(\"hex\")\n\nconst buildCacheKey = (input: ImporterInput) =>\n  `openapiSpecs:${stringToHashKey(JSON.stringify(\"data\" in input ? input.data : input.url))}`\n\nfunction parseImportUrl(url: string): URL {\n  let parsed: URL\n  try {\n    parsed = new URL(url)\n  } catch {\n    throw new HTTPError(\"Invalid import url\", 400)\n  }\n\n  if (!ALLOWED_IMPORT_PROTOCOLS.has(parsed.protocol)) {\n    throw new HTTPError(\"Only HTTP(S) URLs are allowed for query import\", 400)\n  }\n\n  if (parsed.username || parsed.password) {\n    throw new HTTPError(\"Import url must not contain credentials\", 400)\n  }\n\n  return parsed\n}\n\nasync function fetchFromUrl(url: string): Promise<string> {\n  try {\n    // validate protocol / credentials up front for clear 400 errors\n    parseImportUrl(url)\n    // fetchWithBlacklist resolves and validates the target, pins the request to","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/query/import/index.ts#L61-L97","documentation":"parseImportUrl throws this HTTPError(400) when the URL string supplied for a query import cannot be parsed by the URL constructor.","triggerScenarios":"fetchFromUrl invoked from the query import endpoint with an empty, relative, or syntactically invalid URL (missing scheme, spaces, etc.).","commonSituations":"Users pasting CSV/API endpoints without the https:// prefix; form fields left blank; copy-paste introducing whitespace or smart quotes.","solutions":["Provide a fully qualified absolute URL with http:// or https:// scheme","Trim whitespace and stray quotes from the pasted URL","Validate the URL client-side before submitting the import"],"exampleFix":"// before\nconst url = 'myapi.example.com/data.csv'\n// after\nconst url = 'https://myapi.example.com/data.csv'","handlingStrategy":"validation","validationCode":"let parsed: URL\ntry { parsed = new URL(url) } catch { throw new Error('Import source must be an absolute http(s) URL') }","typeGuard":"function isParsableUrl(url: string): boolean {\n  try { new URL(url); return true } catch { return false }\n}","tryCatchPattern":"try {\n  await importSource(url)\n} catch (err) {\n  if (err instanceof HTTPError && err.message === 'Invalid import url') {\n    // prompt user to correct the URL (400 Bad Request)\n  }\n}","preventionTips":["Require the scheme in the import form field","Trim whitespace/quotes from pasted URLs","Validate with new URL() client-side before submitting"],"tags":["validation","url","import","query"],"backgroundTag":"invalid-url-scheme","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}