{"record":{"id":"d4e9ed4ff6a2e722","repo":"Budibase/budibase","slug":"unable-to-retrieve-object","errorCode":null,"errorMessage":"Unable to retrieve object","messagePattern":"Unable to retrieve object","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/backend-core/src/objectStore/objectStore.ts","lineNumber":454,"sourceCode":"\n/**\n * retrieves the contents of a file from the object store, if it is a known content type it\n * will be converted, otherwise it will be returned as a buffer stream.\n */\nexport async function retrieve(\n  bucketName: string,\n  filepath: string\n): Promise<string | stream.Readable> {\n  return await tracer.trace(\"retrieve\", async span => {\n    span.addTags({ bucketName, filepath })\n    const objectStore = ObjectStore()\n    const params = {\n      Bucket: sanitizeBucket(bucketName),\n      Key: sanitizeKey(filepath),\n    }\n    const response = await objectStore.getObject(params)\n    if (!response.Body) {\n      throw new Error(\"Unable to retrieve object\")\n    }\n    span.addTags({\n      contentLength: response.ContentLength,\n      contentType: response.ContentType,\n    })\n    if (STRING_CONTENT_TYPES.includes(response.ContentType)) {\n      span.addTags({ string: true })\n      return response.Body.transformToString()\n    } else {\n      span.addTags({ string: false })\n      // this typecast is required - for some reason the AWS SDK V3 defines its own \"ReadableStream\"\n      // found in the @aws-sdk/types package which is meant to be the Node type, but due to the SDK\n      // supporting both the browser and Nodejs it is a polyfill which causes a type clash with Node.\n      const readableStream =\n        response.Body.transformToWebStream() as ReadableStream\n      return stream.Readable.fromWeb(readableStream)\n    }\n  })","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/Budibase/budibase/blob/a81a902e9a8fe55b467d106765f6638f12e35c49/packages/backend-core/src/objectStore/objectStore.ts#L436-L472","documentation":"retrieve() fetches an object from the configured S3-compatible object store using the AWS SDK v3 getObject command. After the call resolves, it checks response.Body — if the SDK returns a response with no body (empty/missing payload), the library cannot produce a usable stream, so it throws this explicit error instead of returning undefined.","triggerScenarios":"Calling retrieve(bucketName, filepath) when the S3 getObject call succeeds at the protocol level but returns a response with an empty Body — e.g. a zero-byte or deleted-while-listing object, or a proxy/MinIO misconfiguration returning an empty 200 response.","commonSituations":"Serving app definitions, component libraries or plugin JS files (retrieve is used by data, content, getComponentLibraryManifest and pluginJs); hitting an object that was overwritten to zero bytes, a MinIO/CDN proxy stripping the body, or a stale manifest path after an app publish failed halfway.","solutions":["Verify the object actually exists and is non-empty in the bucket (aws s3 ls / MinIO console) — the error usually means a zero-byte or emptied object","Re-upload/re-publish the missing or corrupted asset (e.g. re-publish the app or component library)","Check that the object store (MinIO/S3) and any proxy/CDN in front of it are not stripping response bodies; test with a direct presigned URL","Confirm S3 env config (MINIO_URL, credentials, SELF_HOSTED) points at the correct bucket/region so you are not hitting a wrong-but-existing key"],"exampleFix":"// before\nconst file = await objectStore.retrieve(prodBucket, \"manifest.json\")\n// after\ntry {\n  const file = await objectStore.retrieve(prodBucket, \"manifest.json\")\n} catch (err) {\n  if (err.message === \"Unable to retrieve object\") {\n    // fall back or re-publish asset\n  }\n  throw err\n}","handlingStrategy":"try-catch","validationCode":"const exists = await objectStore.objectExists(bucket, filepath)\nif (!exists) throw new Error(`Object not found: ${filepath}`)","typeGuard":"function hasBody(r: { Body?: unknown }): r is { Body: NonNullable<typeof r.Body> } {\n  return !!r.Body\n}","tryCatchPattern":"try {\n  const file = await objectStore.retrieve(bucket, filepath)\n} catch (err) {\n  if (err.message === \"Unable to retrieve object\") {\n    // treat as missing/empty asset: fallback or re-publish\n  } else throw err\n}","preventionTips":["Check objectExists / metadata before reading critical assets","Monitor for zero-byte objects in the bucket","Keep re-publish tooling handy for app/component-library assets","Validate object store proxy/CDN configuration"],"tags":["s3","object-store","empty-response"],"backgroundTag":"s3-empty-object-response","analyzedSha":"a81a902e9a8fe55b467d106765f6638f12e35c49","analyzedAt":"2026-08-29T01:03:10.972Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}