{"record":{"id":"7f98a752969ca834","repo":"Billionmail/BillionMail","slug":"disk-quota-exceeded-7f98a7","errorCode":null,"errorMessage":"disk quota exceeded","messagePattern":"disk quota exceeded","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/internal/service/compress/zip.go","lineNumber":54,"sourceCode":"\tdefer z.mutex.Unlock()\n\tz.quota = quota\n}\n\n// incWritten increases the size of already compressed file\nfunc (z *Zipper) incWritten(n int64) (err error) {\n\t// if no limit is set, do nothing\n\tif z.quota < 0 {\n\t\treturn nil\n\t}\n\n\tz.mutex.Lock()\n\tdefer z.mutex.Unlock()\n\n\tz.written += n\n\n\t// check if exceeds the limit\n\tif z.quota > -1 && z.written > z.quota {\n\t\terr = errors.New(\"disk quota exceeded\")\n\t\treturn\n\t}\n\n\treturn nil\n}\n\n// compressHelper compresses a file or directory\nfunc (z *Zipper) compressHelper(zw *zip.Writer, path string, fi os.FileInfo, root string) error {\n\theader, err := zip.FileInfoHeader(fi)\n\n\tif err != nil {\n\t\treturn err\n\t}\n\n\theader.Name = strings.TrimPrefix(strings.TrimPrefix(filepath.ToSlash(path), \"./\"), \"/\")\n\theader.Name = strings.TrimPrefix(strings.TrimPrefix(header.Name, root), \"/\")\n\theader.Method = zip.Deflate\n","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/Billionmail/BillionMail/blob/fc36c76c050c3775c5e899faf7403cf0262d2744/core/internal/service/compress/zip.go#L36-L72","documentation":"incWritten is a write-progress callback for the zip compressor. It accumulates the number of bytes written to the archive and, when the compressor was created with a finite quota (z.quota > -1), fails the whole compression operation once the cumulative size exceeds that quota. This turns an unbounded archive job into a bounded one and protects the disk.","triggerScenarios":"Calling Compress/CompressHelper on a source whose total uncompressed size exceeds the quota passed at compressor creation; any subsequent Write callback after written > quota aborts with this error.","commonSituations":"Backing up a directory that grew beyond the configured max archive size; accidentally passing a small quota (or a quota meant to be MB but interpreted as bytes); compressing large logs/uploads where no limit was intended but a stale quota config is in effect.","solutions":["Increase or remove the quota (pass -1 for unlimited) when constructing the zip writer to match the real data size","Exclude oversized files or split the compression job into multiple archives under the quota","Free disk space / verify unit conversion (bytes vs MB) in the quota configuration","Check the source directory size before compressing and fail fast with a clearer user-facing message"],"exampleFix":"// before\nz, err := NewZip(\"out.zip\", 1024*1024) // 1MB quota, data is 50MB\n// after\nz, err := NewZip(\"out.zip\", -1) // unlimited, or quota sized from input estimate","handlingStrategy":"validation","validationCode":"info, err := os.Stat(srcDir); if err != nil || estimateSize(srcDir) > quota { return fmt.Errorf(\"source exceeds quota %d\", quota) }","typeGuard":null,"tryCatchPattern":"files, err := zipSvc.Compress(src, dst, quota)\nif err != nil && strings.Contains(err.Error(), \"disk quota exceeded\") {\n    // raise quota or split archive\n}","preventionTips":["Pass -1 (unlimited) unless a limit is truly intended","Compute expected archive size before compressing","Keep quota units (bytes vs MB) consistent in config","Monitor free disk space before large jobs"],"tags":["quota","filesystem","archive"],"backgroundTag":"disk-quota-exceeded","analyzedSha":"fc36c76c050c3775c5e899faf7403cf0262d2744","analyzedAt":"2026-09-05T21:28:54.019Z","contentChangedAt":"2026-09-05T21:28:54.019Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}