Stirling-Tools/Stirling-PDF · error · Error

Failed to create ZIP file: ${error instanceof Error ? error.

Error message

Failed to create ZIP file: ${error instanceof Error ? error.message : "Unknown error"}

What it means

Wraps any exception thrown inside createZipFromFiles: a File whose arrayBuffer() rejects (revoked blob), JSZip generateAsync failing (out of memory), or File construction failing. The original error is preserved as cause.

Source

Thrown at frontend/editor/src/core/services/zipFileService.ts:176

        const content = await file.arrayBuffer();
        zip.file(file.name, content);
      }

      // Generate ZIP blob
      const zipBlob = await zip.generateAsync({
        type: "blob",
        compression: "DEFLATE",
        compressionOptions: { level: 6 },
      });

      const zipFile = new File([zipBlob], zipFilename, {
        type: "application/zip",
        lastModified: Date.now(),
      });

      return { zipFile, size: zipFile.size };
    } catch (error) {
      throw new Error(
        `Failed to create ZIP file: ${error instanceof Error ? error.message : "Unknown error"}`,
        {
          cause: error,
        },
      );
    }
  }

  /**
   * Extract PDF files from a ZIP archive
   */
  async extractPdfFiles(
    file: File,
    onProgress?: (progress: ZipExtractionProgress) => void,
  ): Promise<ZipExtractionResult> {
    const result: ZipExtractionResult = {
      success: false,
      extractedFiles: [],

View on GitHub (pinned to 9ef20dcab8)

Solutions

  1. Ensure all File objects are still valid (not revoked) at call time.
  2. Reduce total input size or zip in smaller batches.
  3. Catch the error, inspect e.cause, and surface it to the user; retry once for transient memory pressure.
  4. Validate inputs are real File instances before calling.

Example fix

// before
const content = await file.arrayBuffer();
zip.file(file.name, content);
// ...
const zipBlob = await zip.generateAsync({ type: 'blob', compression: 'DEFLATE' });

// after
if (!files.every((f) => f instanceof File && f.size >= 0)) {
  throw new Error('All inputs must be valid File objects.');
}
// stream large sets in chunks instead of one giant generateAsync
for (const f of files) {
  zip.file(f.name, await f.arrayBuffer());
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!files.every((f) => f instanceof File)) {
  throw new Error('createZipFromFiles requires File instances.');
}
if (files.reduce((n, f) => n + f.size, 0) > MAX_ZIP_BYTES) {
  throw new Error('Combined size too large to zip in memory.');
}

Type guard

function areValidFiles(files: unknown[]): files is File[] {
  return files.every((f) => f instanceof File && typeof f.arrayBuffer === 'function');
}

Try / catch

try {
  return await zipFileService.createZipFromFiles(files, name);
} catch (e) {
  const cause = (e instanceof Error && e.cause) ? e.cause : e;
  console.error('ZIP creation failed:', cause);
  throw e;
}

Prevention

When it happens

Trigger: A File/Blob passed in is no longer readable (blob URL revoked), the combined content exceeds available memory during DEFLATE compression, or a non-File value lacks arrayBuffer.

Common situations: Revoked object URLs; very large or many files exhausting the heap/WASM; Safari blob backing-store loss; concurrent zip operations competing for memory.

Related errors


AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13). Data as JSON: /api/errors/caac868d8f3b2ba2. Report an issue: GitHub.