There is a workaround here, confirmed working.
https://www.reddit.com/r/PowerApps/s/77QhBqTn1Z
The auto generated services don't incorporate the full capabilities of the API you can bypass this by directly calling PluginBridge
// ── Why we bypass the SDK for file uploads ──────────────────────────
// The Power Apps Code Apps SDK (DocumentsService.create / client.executeAsync)
// cannot upload files to a SharePoint document library for two reasons:
//
// 1. createRecordAsync() issues a POST to the /items endpoint, but SharePoint
// document libraries require SPFileCollection.Add() (the /files endpoint).
//
// 2. executeAsync() always passes the body through JSON.stringify(), which
// corrupts binary content and wraps text in extra double-quotes.
//
// To work around this, we call the Power Apps runtime plugins directly:
// - AppPowerAppsClientPlugin → get connection config (runtime URL, dataset, etc.)
// - AppIdentityServicePlugin → get a connector auth token
// - AppHttpClientPlugin → send the raw HTTP request with a Blob body
//
// This is the same HTTP pipeline the SDK uses internally (see runtimeDataClient.js),
// just without the JSON.stringify wrapper on the request body.
// ─────────────────────────────────────────────────────────────────────
// Step 1: Get connection configs to find the SharePoint connector's runtime URL,
// connection name, dataset (site URL), and API ID.
const connConfigs = await executePluginAsync<Record<string, any>>(
'AppPowerAppsClientPlugin',
'loadAppConnectionsAsync_v2',
[],
);
// Step 2: Find the SharePoint connection reference from the returned configs.
// Keys are lowercased by the SDK. We match on the apiId containing 'shared_sharepointonline'.
const spKey = Object.keys(connConfigs).find(
(k) => connConfigs[k]?.apiId?.indexOf('shared_sharepointonline') !== -1,
);
if (!spKey) throw new Error('SharePoint connection reference not found.');
const spConn = connConfigs[spKey];
const runtimeUrl: string = spConn.runtimeUrl;
const connectionName: string = spConn.connectionName;
const datasetName: string = spConn.datasetName; // The SharePoint site URL
const apiId: string = spConn.apiId;
// Step 3: Build the CreateFile URL.
// SharePoint datasets must be double-encoded (once here, once by the HTTP pipeline).
// folderPath must point to the library's server-relative root folder name.
// NOTE: The root folder name may differ by locale (e.g. "Shared Documents" in English,
// "Freigegebene Dokumente" in German). Check your library's actual folder name.
const encodedDataset = encodeURIComponent(encodeURIComponent(datasetName));
const folderPath = encodeURIComponent('/Shared Documents');
const fileName = encodeURIComponent(file.name);
const uploadUrl = `${runtimeUrl}/${connectionName}/datasets/${encodedDataset}/files?folderPath=${folderPath}&name=${fileName}`;
// Step 4: Get an auth token scoped to the SharePoint connector.
// The 'paauth' scheme is used by Power Apps connector proxy (not a standard Bearer token).
const token = await executePluginAsync<string>(
'AppIdentityServicePlugin',
'getAppAccessTokenAsync',
[apiId],
);
// Step 5: Read the file as a raw binary Blob.
// Using Blob instead of a string preserves binary content for all file types.
const fileBuffer = await file.arrayBuffer();
const fileBlob = new Blob([fileBuffer], { type: file.type || 'application/octet-stream' });
// Step 6: Call the HTTP plugin directly, sending the Blob as the request body.
// This avoids the SDK's JSON.stringify which would corrupt the file content.
await executePluginAsync<any>(
'AppHttpClientPlugin',
'sendHttpAsync',
[
{
url: uploadUrl,
method: 'POST',
requestSource: 'PublishedApp',
allowSessionStorage: true,
returnDirectResponse: true,
headers: {
Accept: 'application/json',
'x-ms-protocol-semantics': 'cdp', // Required: tells proxy this is a connector call
ServiceNamespace: 'documents', // Must match the data source name in power.config.json
Authorization: `paauth ${token}`, // Power Apps connector auth (not Bearer)
'Content-Type': file.type || 'application/octet-stream',
},
},
fileBlob, // Raw binary body — NOT JSON-serialized
'arraybuffer', // Response type
],
);