Skip to content

Commit b7db38a

Browse files
committed
fix(sandbox): consistency and cleanup pass on doc-gen tasks and worker
- DOCX addImage: upfront width/height validation (matches PDF/PPTX pattern) - PDF embedImage: remove dead Buffer ternary; drop redundant size guard already enforced in getFileBase64 - isolated-vm-worker: add friendly MemoryLimitError branch in both execute paths so OOM produces a clear message instead of a raw V8 error
1 parent 925d2ba commit b7db38a

3 files changed

Lines changed: 39 additions & 9 deletions

File tree

apps/sim/lib/execution/isolated-vm-worker.cjs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,21 @@ async function executeCode(request, executionId) {
398398
}
399399
}
400400

401+
if (
402+
err.message.includes('Array buffer allocation failed') ||
403+
err.message.includes('memory limit')
404+
) {
405+
return {
406+
result: null,
407+
stdout,
408+
error: {
409+
message:
410+
'Execution exceeded memory limit (256 MB). Reduce image sizes or split the work into smaller batches.',
411+
name: 'MemoryLimitError',
412+
},
413+
}
414+
}
415+
401416
return {
402417
result: null,
403418
stdout,
@@ -937,6 +952,23 @@ async function executeTask(request, executionId) {
937952
timings,
938953
}
939954
}
955+
956+
if (
957+
err.message?.includes('Array buffer allocation failed') ||
958+
err.message?.includes('memory limit')
959+
) {
960+
return {
961+
result: null,
962+
stdout,
963+
error: {
964+
message:
965+
'Execution exceeded memory limit (256 MB). Reduce image sizes or split the work into smaller batches.',
966+
name: 'MemoryLimitError',
967+
},
968+
timings,
969+
}
970+
}
971+
940972
return {
941973
result: null,
942974
stdout,

apps/sim/sandbox-tasks/docx-generate.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ export const docxGenerateTask = defineSandboxTask<SandboxTaskInput>({
5353
* new docx.Paragraph({ children: [await addImage('abc123', { width: 200, height: 100 })] })
5454
*/
5555
globalThis.addImage = async function addImage(fileId, opts) {
56+
if (!opts || opts.width == null || opts.height == null) {
57+
throw new Error('addImage: opts must include width and height (in pixels)');
58+
}
5659
const dataUri = await globalThis.getFileBase64(fileId);
5760
const comma = dataUri.indexOf(',');
5861
if (comma === -1) throw new Error('addImage: invalid data URI (no comma separator)');
@@ -63,11 +66,11 @@ export const docxGenerateTask = defineSandboxTask<SandboxTaskInput>({
6366
const ext = extMap[mime];
6467
if (!ext) throw new Error('addImage: unsupported image type "' + mime + '". Use PNG, JPEG, GIF, BMP, or SVG.');
6568
if (!globalThis.Buffer) throw new Error('addImage: Buffer polyfill missing — ensure docx bundle is loaded');
66-
const { width, height, type: _t, data: _d, transformation: userTransform, ...passThrough } = opts || {};
69+
const { width, height, type: _t, data: _d, transformation: userTransform, ...passThrough } = opts;
6770
return new globalThis.docx.ImageRun(Object.assign(passThrough, {
6871
data: globalThis.Buffer.from(base64, 'base64'),
6972
type: ext,
70-
transformation: Object.assign({ width: width ?? 200, height: height ?? 200 }, userTransform || {}),
73+
transformation: Object.assign({ width, height }, userTransform || {}),
7174
}));
7275
};
7376
`,

apps/sim/sandbox-tasks/pdf-generate.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,12 @@ export const pdfGenerateTask = defineSandboxTask<SandboxTaskInput>({
3232
if (!dataUri || typeof dataUri !== 'string') {
3333
throw new Error('embedImage: dataUri must be a non-empty string');
3434
}
35-
if (dataUri.length > _MAX_IMG_B64) {
36-
throw new Error(
37-
'embedImage: image exceeds the 6 MB embed limit (~8 MB base64). Use a smaller/compressed image.'
38-
);
39-
}
4035
const comma = dataUri.indexOf(',');
4136
if (comma === -1) throw new Error('embedImage: invalid data URI (no comma separator)');
4237
const header = dataUri.slice(0, comma);
4338
const base64 = dataUri.slice(comma + 1);
44-
const binary = globalThis.Buffer ? globalThis.Buffer.from(base64, 'base64') : null;
45-
if (!binary) throw new Error('Buffer polyfill missing');
39+
if (!globalThis.Buffer) throw new Error('embedImage: Buffer polyfill missing');
40+
const binary = globalThis.Buffer.from(base64, 'base64');
4641
const mime = header.split(';')[0].split(':')[1] || '';
4742
// image/jpg is non-standard but tolerated; the canonical MIME is image/jpeg
4843
if (mime === 'image/png') return globalThis.pdf.embedPng(binary);

0 commit comments

Comments
 (0)