cancel
Showing results for 
Search instead for 
Did you mean: 

OData $batch Request Limitation in SAP Build Apps

Yves123
Explorer
202

I’m trying to update multiple items in SAP S/4HANA using an OData $batch request from  SAP Build Apps . I generate the correct multipart/mixed payload with boundaries in JavaScript. However, when sending this via the HTTP Destination Request, I get the error:
"Invalid body type for binary request. Please provide a file object."

  • SAP Build Apps only accepts a File object (from a File Picker) for binary bodies—not a programmatically created Blob or string.

  • Other body types (JSON, x-www-form-urlencoded, multipart/form-data) are not compatible with OData $batch, which strictly requires multipart/mixed.

  • This blocks seamless, programmatic OData batch operations—users would have to manually upload a file, which breaks UX.

Question:
Has anyone found a workaround for this? Is there a way to send a multipart/mixed OData $batch request from SAP Build Apps without requiring a File Picker or user-uploaded file? Or is this a known limitation with any planned fix?

@Dan_Wroblewski  
Additional information:
JS createBatchPayload:

const records = inputs.input1; // List of selected items
const newGroup = inputs.input2; // e.g., "101", "102", etc.

const batchBoundary = "batch_test";
const changesetBoundary = "changeset_test";

// Log inputs
console.log(" createBatchPayload.js");
console.log(" Records:", JSON.stringify(records, null, 2));
console.log(" New Purchasing Group:", newGroup);

// Safety check
if (!records || !Array.isArray(records) || records.length === 0) {
console.warn(" No records provided to batch payload.");
return { result: "" };
}

if (!newGroup || typeof newGroup !== "string" || newGroup.trim() === "") {
console.warn(" Missing or invalid Purchasing Group input.");
return { result: "" };
}

let batchParts = [];

records.forEach((item, index) => {
const patchBlock = [
`--${changesetBoundary}`,
"Content-Type: application/http",
"Content-Transfer-Encoding: binary",
`Content-ID: ${index + 1}`,
"",
`PATCH PurchaseReqnItem(PurchaseRequisition='${item.Document}',PurchaseRequisitionItem='${item.DocumentItem}') HTTP/1.1`,
"Content-Type: application/json",
"If-Match: *",
"",
JSON.stringify({ PurchasingGroup: newGroup }),
""
].join("\n");

batchParts.push(patchBlock);
});

const payload = [
`--${batchBoundary}`,
`Content-Type: multipart/mixed; boundary=${changesetBoundary}`,
"",
...batchParts,
`--${changesetBoundary}--`,
`--${batchBoundary}--`
].join("\n");

console.log(" Final Batch Payload:\n", payload);

return { result: payload };

JS converToBlob:

// Input: outputs.createBatchPayload.result (text payload)
// Output: Blob ready for HTTP request

const payloadText = inputs.input1;
const boundary = "batch_test";

console.log(" convertToBlob.js");
console.log(" Input payload length:", payloadText.length);

// Validate payload structure
if (!payloadText.includes(`--${boundary}`)) {
console.error(" Missing batch boundary markers");
return { blob: null };
}

// Create Blob with correct MIME type
const blob = new Blob([payloadText], {
type: `multipart/mixed; boundary=${boundary}`
});

console.log(" Created Blob:", {
size: blob.size,
type: blob.type
});

// Optional verification
const reader = new FileReader();
reader.onload = () => {
console.log(" Blob content sample:", reader.result.substring(0, 200));
};
reader.readAsText(blob);

return { blob: blob };

Accepted Solutions (0)

Answers (0)