{"record":{"id":"ec35cab42f2df958","repo":"Budibase/budibase","slug":"import-data-or-url-is-required","errorCode":null,"errorMessage":"Import data or url is required","messagePattern":"Import data or url is required","errorType":"http","errorClass":"HTTPError","httpStatus":400,"severity":"error","filePath":"packages/server/src/api/controllers/query/import/index.ts","lineNumber":162,"sourceCode":"  )\n  return result\n}\n\nexport async function createImporter(\n  input: { data?: string } | { url?: string }\n): Promise<RestImporter> {\n  let cacheKeyBase: string | undefined\n  let data: string | undefined\n  if (\"url\" in input && input.url) {\n    cacheKeyBase = buildCacheKey({ url: input.url })\n    data = await urlToSpecs(input.url, cacheKeyBase)\n  } else if (\"data\" in input) {\n    data = input.data\n  }\n\n  data = data?.trim()\n  if (!data) {\n    throw new HTTPError(\"Import data or url is required\", 400)\n  }\n\n  let cachedType: string | undefined\n  const importerTypeCacheKey = cacheKeyBase && `${cacheKeyBase}:type`\n  if (importerTypeCacheKey) {\n    const client = await redis.clients.getOpenapiImportSpecsClient()\n    cachedType = await client.get(importerTypeCacheKey)\n  }\n  const importer = await RestImporter.init(data, cachedType)\n\n  if (!cachedType && importerTypeCacheKey) {\n    const client = await redis.clients.getOpenapiImportSpecsClient()\n    await client.store(\n      importerTypeCacheKey,\n      importer.getSource().getImportSource(),\n      cache.TTL.ONE_DAY * OPENAPI_SPEC_CACHE_TTL_DAYS\n    )\n  }","sourceCodeStart":144,"sourceCodeEnd":180,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/server/src/api/controllers/query/import/index.ts#L144-L180","documentation":"createImporter requires either a `url` or non-empty `data` input describing the import payload. After trimming, if no data string is present it throws HTTPError 400 'Import data or url is required'. It prevents creating an importer from an empty/undefined payload.","triggerScenarios":"Calling createImporter/getImportInfo with `{}` (neither key), `{ data: \"\" }`, `{ data: \"   \" }` (whitespace only), or `{ data: undefined }`.","commonSituations":"A frontend form submits before the user pastes a spec; a file upload reads as an empty string because the wrong form field was read; an automation passes a variable that resolved to empty.","solutions":["Ensure the request body includes either `data` (the spec/curl string) or `url`","Check that the file/field you read the spec from is actually populated before sending","Trim/validate client-side and show a validation message when the field is empty"],"exampleFix":"// before\nawait createImporter({ data: fileInput.value ?? \"\" }) // throws when empty\n// after\nif (!fileInput.value?.trim()) throw new Error(\"Please provide a spec or URL\")\nawait createImporter({ data: fileInput.value })","handlingStrategy":"validation","validationCode":"function validateImporterInput(input: { data?: string; url?: string }) {\n  if (!input.data?.trim() && !input.url?.trim()) {\n    throw new Error(\"Provide either a spec payload (data) or a URL\")\n  }\n  return input as { data: string } | { url: string }\n}","typeGuard":"const hasImportPayload = (i: unknown): i is { data: string } | { url: string } =>\n  typeof i === \"object\" && i !== null &&\n  ((\"data\" in i && typeof (i as any).data === \"string\" && !!(i as any).data.trim()) ||\n   (\"url\" in i && typeof (i as any).url === \"string\" && !!(i as any).url.trim()))","tryCatchPattern":"null","preventionTips":["Validate the form field is non-empty (after trim) before submitting the import request","Ensure you read the correct file/form field and that file reads are awaited","Guard automations against variables that may resolve to empty strings"],"tags":["validation","bad-request","import"],"backgroundTag":"missing-required-payload","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}