How to troubleshooting the empty folder pruner
- Step 1Confirm it's a ZIP — If you see 'Not a valid ZIP archive.', the file isn't a ZIP (often a renamed 7z/rar/tar.gz). Verify with Auto Format Detector — it reads magic bytes and reports the true format.
- Step 2Check the tier limits — Free caps at 50 MB and 500 entries; Pro at 500 MB / 50,000; Pro+Media and Developer at 2 GB / 500,000. Both checks run before pruning, so an oversize file or entry count fails instantly.
- Step 3Rule out encryption — If decompression fails on a password-protected ZIP, that's expected — fflate can't read encrypted entries. Confirm with Encrypted Archive Detector, then decrypt before pruning.
- Step 4Read the 'removed' count — If 'Empty dirs removed = 0', there were no unreferenced directory records — every folder held a file. That's the correct result, not a failure.
- Step 5Explain unexpected timestamp changes — The output rebuilds the ZIP, resetting every entry's date to now. If that breaks your checksum, run Timestamp Normaliser afterward.
- Step 6Try a repair if corrupt — If the central directory is damaged, parsing returns nothing and you get 'Not a valid ZIP archive.' Recover with Corrupted ZIP Repair, then prune the repaired file.
Error and symptom decoder
What the Empty Folder Pruner reports, what it means, and the fix. Error strings come directly from lib/archive/archive-processor.ts and the tier-limit checks.
| Message or symptom | Cause | Fix |
|---|---|---|
| 'Not a valid ZIP archive.' | No ZIP End-Of-Central-Directory found — wrong format or corrupt CD | Verify with Auto Format Detector; repair with Corrupted ZIP Repair |
| Tier limit (size) | ZIP bigger than your plan's cap (50 MB / 500 MB / 2 GB) | Upgrade tier or split with Archive Splitter |
| Tier limit (entries) | More entries than your plan allows (500 / 50,000 / 500,000) | Upgrade tier; remember empty dir records count too |
| Decompression fails | ZIP is encrypted (AES/ZipCrypto) — fflate can't read it | Decrypt first; detect with Encrypted Archive Detector |
| 'Empty dirs removed = 0' | No unreferenced directory records — nothing to prune | Not a bug; the archive had no empty folders |
| Timestamps all changed | ZIP rebuilt with fflate, which resets entry dates | Run Timestamp Normaliser after pruning |
Tier limits that apply to the Empty Folder Pruner
Limits are enforced per input file before pruning begins (lib/tier-limits.ts, archive family). The pruner reads ONE ZIP at a time on every tier — it is not a batch tool, so the batch-files column only matters for sibling tools that accept folders. entryLimit counts every entry in the ZIP central directory, including the empty directory records you are trying to remove.
| Tier | Max ZIP size | Max entries per ZIP | Files per run |
|---|---|---|---|
| Free | 50 MB | 500 entries | 1 |
| Pro | 500 MB | 50,000 entries | 20 (other tools) |
| Pro + Media | 2 GB | 500,000 entries | 100 (other tools) |
| Developer | 2 GB | 500,000 entries | unlimited (other tools) |
| Enterprise | unlimited | unlimited | unlimited |
Cookbook
The exact symptoms you'll see and how to confirm the cause. Messages match the tool's real output.
Renamed archive rejected
A .zip that's actually a 7z (someone renamed it) fails immediately because there's no ZIP central directory. The detector reveals the truth.
Action: drop backup.zip -> 'Not a valid ZIP archive.' Auto Format Detector on backup.zip: Reported format: 7-Zip (magic bytes 37 7A BC AF 27 1C) Fix: it's a .7z. Extract/convert it, or prune only true ZIPs.
Tier limit hit before processing
An 80 MB ZIP on the free tier fails the size check before any pruning. The error appears instantly, not after a long spinner.
Free tier, input = release.zip (80 MB) -> Tier limit exceeded: 80 MB > 50 MB free cap Options: - upgrade to Pro (500 MB) - split with Archive Splitter, prune parts separately
Encrypted ZIP won't decompress
fflate's unzipSync can't read AES or ZipCrypto entries, so a password-protected ZIP fails. Detect the encryption, decrypt, then prune.
Action: drop secure.zip -> decompression fails Encrypted Archive Detector on secure.zip: Encryption: AES-256 Fix: decrypt with your password in a ZIP tool, prune the plaintext copy.
Nothing removed (and that's correct)
Every directory record in the ZIP has a file under it, so there are no empties. 'Empty dirs removed = 0' is the right answer.
Input: src/main.py src/util.py tests/test_main.py src/ tests/ (both have files) Result: Empty dirs removed = 0, Entries = 5 This is correct — there were no empty folders.
Checksum changed after pruning
Even a no-op prune rebuilds the ZIP and resets timestamps, so the SHA-256 differs from the original. Normalise timestamps to get a stable hash.
sha256(release.zip) = a1b2... sha256(release-pruned.zip) = 9f3c... (differs even with 0 dirs removed) Reason: timestamps reset on rebuild. Fix: Timestamp Normaliser -> fixed date -> stable, comparable hash.
Edge cases and what actually happens
'Not a valid ZIP archive.'
RejectedThe parser found no ZIP central directory. The file is either a different format (7z/rar/tar.gz renamed) or has a corrupt central directory. Check with Auto Format Detector; if it really is a damaged ZIP, try Corrupted ZIP Repair.
File over the size cap
Tier limit exceededFree 50 MB, Pro 500 MB, Pro+Media/Developer 2 GB. The check runs first, so the failure is immediate. Upgrade or split with Archive Splitter.
Too many entries
Tier limit exceededFree 500, Pro 50,000, higher tiers 500,000 entries. The empty directory records you want gone still count toward this, so a folder-heavy ZIP can trip it even when small.
Encrypted ZIP fails to open
Not supportedfflate's unzipSync cannot read AES or ZipCrypto entries, so decompression fails. Detect with Encrypted Archive Detector, decrypt, then prune.
Zero empty dirs removed
ExpectedEvery directory record was referenced by a file, so nothing qualified for pruning. This is the correct outcome, not an error — check the metric to confirm.
All timestamps changed
ExpectedThe output is a freshly built ZIP and fflate writes the current time to entries when no mtime is supplied. Use Timestamp Normaliser for stable dates.
Output checksum differs even with 0 removed
ExpectedRebuilding resets timestamps and may re-apply fflate level-6 compression, so the bytes differ from the original even when no entries were removed. Normalise timestamps before comparing hashes.
Browser tab runs out of memory on a huge ZIP
FailedThe whole archive is decompressed in RAM. A 2 GB ZIP near the cap can exhaust device memory, especially on mobile. Use a desktop with more RAM or a CLI for very large files.
Wanted a preview of what would be pruned
Not availableThere is no report-only mode in the current build — the tool prunes and reports the count. To inspect first, list entries with File Listing Generator before running.
macOS .DS_Store / __MACOSX still present
By designThose are files, not empty directories, so the pruner keeps them. Strip them with Filename Sanitiser, then prune if any folders became empty.
Frequently asked questions
Why does it say 'Not a valid ZIP archive.'?
The file has no ZIP central directory. It's usually a renamed 7z/rar/tar.gz, or a ZIP with a corrupt central directory. Confirm the real format with Auto Format Detector.
Why did it fail before processing even started?
Size and entry-count checks run first. If the ZIP exceeds your tier's cap (50 MB / 500 entries on free), it fails instantly with a tier-limit error.
Why won't my password-protected ZIP open?
fflate can't read encrypted entries (AES or ZipCrypto), so decompression fails. Decrypt the ZIP first, then prune the plaintext copy.
Why were zero empty dirs removed?
Because every directory record had at least one file under it. There were no empties to prune, so 'Empty dirs removed = 0' is the correct result.
Why did all my timestamps change?
The tool rebuilds the ZIP and fflate stamps every entry with the current time. Run Timestamp Normaliser afterward if you need stable dates.
Why is the output a different size or checksum if nothing was removed?
Rebuilding resets timestamps and re-applies fflate level-6 compression, so the bytes differ even on a no-op. That's expected; normalise timestamps to compare hashes meaningfully.
It's stuck on 'Processing' — what now?
Very large ZIPs near the 2 GB cap can take a while or exhaust memory because everything is decompressed in RAM. Hard-refresh (Ctrl+Shift+R) to clear a stale build, and try a smaller file or a desktop with more RAM.
Can it prune a 7z or tar.gz?
No — ZIP only. Convert to ZIP with Archive Format Converter first, or use a CLI for non-ZIP formats.
Why didn't it remove .DS_Store or __MACOSX?
Those are files, not empty directories, so the pruner keeps them. Use Filename Sanitiser to strip macOS cruft.
Can I preview what will be pruned first?
No report-only mode exists in the current build. List the archive with File Listing Generator to see directory entries before you prune.
Does it ever delete my files?
No. Only directory records with no file under them are removed. Every file entry is preserved byte-for-byte.
My central directory is corrupt — can I still prune?
Not directly; parsing fails and you get 'Not a valid ZIP archive.' Recover what you can with Corrupted ZIP Repair, then prune the repaired ZIP.
Privacy first
Every JAD Archive tool runs entirely in your browser using fflate, @zip.js/zip.js, and the libarchive WASM bridge. Your archives never leave your device — verified by zero outbound network requests during processing.