archiver
semver
>=5.0.0postconditions24functions7last verified2026-06-18coverage score100%Postconditions — what we check
- archiver · missing-error-handlererrorWhenarchiver instance created without error event handlerThrows
Emits 'error' event that crashes process if not handledRequired handlingCaller MUST attach error event handler immediately after creating archiver instance. Without error handler, unhandled 'error' events crash the entire Node.js process. CRITICAL: This is the #1 production bug (70% of codebases). Always add: archive.on('error', (error) => { handle_error(error); })costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[1] - archiver · missing-warning-handlererrorWhenarchiver instance created without warning event handlerThrows
Emits 'warning' event for non-blocking errors (ENOENT, file access failures)Required handlingCaller MUST attach warning event handler to catch non-blocking errors. Without warning handler, file access errors (ENOENT) go unnoticed, resulting in incomplete archives and silent data loss. CRITICAL: This is production bug #2 (80% of codebases). Always add: archive.on('warning', (err) => { if (err.code !== 'ENOENT') throw err; })costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[2] - archiver · compression-errorerrorWhenCompression fails during archive creationThrows
Emits 'error' event with Error objectRequired handlingCaller MUST handle compression errors via error event handler. Common causes: out of memory, invalid compression options, stream errors. Error event is emitted during finalize().costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[3] - archiver · file-access-errorwarningWhenFile or directory is missing or inaccessible (ENOENT, EACCES)Throws
Emits 'warning' event for non-blocking errors like ENOENTRequired handlingCaller MUST handle warning events to detect missing or inaccessible files. Warning events are emitted for individual file failures during directory archiving. Check err.code === 'ENOENT' to differentiate from fatal errors.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[2] - archiver · missing-finalizeerrorWhenArchive operations performed but finalize() never calledThrows
Process exits silently with code 0 when event loop emptiesRequired handlingCaller MUST call archive.finalize() after adding all files. Without finalize(), the archive is never completed and the process exits silently with code 0 once the event loop is empty. This is extremely difficult to debug.costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[4] - finalize · finalize-after-aborterrorWhenfinalize() called after abort() has been calledThrows
Emits 'error' event with ArchiverError code='ABORTED' and returns rejected PromiseRequired handlingIf finalize() is called on an aborted archive, it emits an 'error' event with ArchiverError{ code: 'ABORTED', message: 'archive was aborted' } and returns a rejected Promise. Callers MUST handle the rejected promise (try/catch or .catch()) AND have an error event handler attached, as both are triggered simultaneously. Silently swallowing the rejected Promise hides the abort error.costlowin prodimmediate exceptionusers seelost datavisibilitysilent - finalize · finalize-double-callwarningWhenfinalize() called a second time while first finalization is in progressThrows
Emits 'error' event with ArchiverError code='FINALIZING' and returns rejected PromiseRequired handlingCalling finalize() a second time emits ArchiverError{ code: 'FINALIZING', message: 'archive already finalizing' } as an error event and returns a rejected Promise. This commonly happens in request handlers that call finalize() in a finally block after already calling it in a try block. Guard with a finalized flag.costlowin prodimmediate exceptionusers seelost datavisibilitysilentSources[5] - finalize · finalize-incomplete-outputerrorWhenawait archive.finalize() resolves but output destination stream is not yet fully writtenThrows
No error — silently produces truncated/corrupt archive when output stream closes after finalize() resolvesRequired handlingThe finalize() Promise resolves when the archive module's internal stream ends (the 'end' event on the compression module), NOT when the piped destination (e.g. fs.createWriteStream) finishes writing to disk. For large archives (100+ files or >100MB), the OS write buffer may not have flushed by the time the Promise resolves. Callers MUST also await the 'close' event on the output stream: const output = fs.createWriteStream('archive.zip'); archive.pipe(output); await archive.finalize(); await new Promise((resolve, reject) => { output.on('close', resolve); output.on('error', reject); }); Skipping the 'close' wait produces corrupt archives intermittently under load.costmediumin prodsilent failureusers seelost datavisibilitysilent - append · append-after-finalizeerrorWhenappend() called after finalize() or abort() has been calledThrows
Emits 'error' event with ArchiverError code='QUEUECLOSED' — entry silently droppedRequired handlingIf append() is called after finalize() or abort(), it emits ArchiverError{ code: 'QUEUECLOSED', message: 'queue closed' } via the 'error' event and returns without enqueuing the entry. The entry is SILENTLY DROPPED. This happens in background workers that race with finalize() calls. Callers must check archive state before calling append() in async contexts or catch the QUEUECLOSED error specifically.costmediumin prodsilent failureusers seelost datavisibilitysilent - append · append-missing-entry-nameerrorWhenappend() called without data.name or with empty string nameThrows
Emits 'error' event with ArchiverError code='ENTRYNAMEREQUIRED'Required handlingIf the entry data object is missing the 'name' field or name is an empty string, archiver emits ArchiverError{ code: 'ENTRYNAMEREQUIRED', message: 'entry name must be a non-empty string value' }. The entry is dropped. This silently produces archives missing expected files. Always provide a non-empty name in data: { name: 'path/to/file' }.costlowin prodsilent failureusers seelost datavisibilitysilent - append · append-invalid-source-typeerrorWhenappend() called with source that is not a Buffer, Readable stream, or stringThrows
Emits 'error' event with ArchiverError code='INPUTSTEAMBUFFERREQUIRED'Required handlingIf source is not a Buffer, Readable stream, or string, archiver emits ArchiverError{ code: 'INPUTSTEAMBUFFERREQUIRED', message: 'input source must be valid Stream or Buffer instance' }. This commonly happens when passing a Promise instead of a stream, or passing null/undefined. Always validate source type before calling append().costlowin prodsilent failureusers seelost datavisibilitysilent - append · append-directory-entry-unsupportederrorWhenappend() called with data.type === 'directory' on a JSON-format archiver instanceThrows
Emits 'error' event with ArchiverError code='DIRECTORYNOTSUPPORTED'Required handlingThe JSON format does not support directory entries. If append() is called with data.type === 'directory' on a JsonArchive, archiver emits ArchiverError{ code: 'DIRECTORYNOTSUPPORTED', message: 'support for directory entries not defined by module', data: { name } }. The entry is silently dropped from the archive. Only set entry type === 'directory' when using ZipArchive or TarArchive. For JSON format, omit the type field and pass only file content.costlowin prodsilent failureusers seelost datavisibilitysilent - append · append-stream-error-not-propagatederrorWhenReadable stream passed to append() emits its own 'error' eventThrows
Stream error is NOT automatically forwarded to archiver's error event — process may crashRequired handlingWhen a Readable stream passed to append() emits its own 'error' event (e.g. network failure, file read error), that error is NOT automatically forwarded to the archiver instance's 'error' event. The unhandled stream error event crashes the Node.js process. Callers MUST attach an error handler to each stream before passing it to append(): const stream = fs.createReadStream('file.txt'); stream.on('error', (err) => archive.emit('error', err)); archive.append(stream, { name: 'file.txt' });costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisibleSources[8] - directory · directory-after-finalizeerrorWhendirectory() called after finalize() or abort()Throws
Emits 'error' event with ArchiverError code='QUEUECLOSED'Required handlingIf directory() is called after finalize() or abort(), it emits ArchiverError{ code: 'QUEUECLOSED' }. The directory contents are silently dropped from the archive. Guard directory() calls with state checks or avoid calling after finalize().costmediumin prodsilent failureusers seelost datavisibilitysilentSources[5] - directory · directory-invalid-dirpatherrorWhendirectory() called with non-string or empty dirpathThrows
Emits 'error' event with ArchiverError code='DIRECTORYDIRPATHREQUIRED'Required handlingIf dirpath is not a string or is an empty string, archiver emits ArchiverError{ code: 'DIRECTORYDIRPATHREQUIRED', message: 'diretory dirpath argument must be a non-empty string value' }. Validate dirpath before calling directory().costlowin prodsilent failureusers seelost datavisibilitysilentSources[5] - directory · directory-function-invalid-returnwarningWhenData transformation function passed to directory() returns invalid value (not false or EntryData object)Throws
Emits 'error' event with ArchiverError code='DIRECTORYFUNCTIONINVALIDDATA'Required handlingThe optional third argument to directory() can be a function that transforms EntryData per-file. If this function returns anything other than false (to skip the entry) or a valid EntryData object, archiver emits ArchiverError{ code: 'DIRECTORYFUNCTIONINVALIDDATA' }. Return false to skip a file or the modified entry object to include it. Never return null, undefined, or other falsy values.costlowin prodsilent failureusers seelost datavisibilitysilentSources[5] - file · file-after-finalizeerrorWhenfile() called after finalize() or abort()Throws
Emits 'error' event with ArchiverError code='QUEUECLOSED'Required handlingIf file() is called after finalize() or abort(), the file is silently dropped and archiver emits ArchiverError{ code: 'QUEUECLOSED' }. Avoid calling file() after finalize() or guard with a state check.costmediumin prodsilent failureusers seelost datavisibilitysilentSources[5] - file · file-invalid-filepatherrorWhenfile() called with non-string or empty filepathThrows
Emits 'error' event with ArchiverError code='FILEFILEPATHREQUIRED'Required handlingIf filepath is not a string or is an empty string, archiver emits ArchiverError{ code: 'FILEFILEPATHREQUIRED', message: 'file filepath argument must be a non-empty string value' }. Always validate filepath before passing to file().costlowin prodsilent failureusers seelost datavisibilitysilentSources[5] - glob · glob-no-matcheswarningWhenglob() pattern matches zero files and finalize() is calledThrows
No error emitted — archive is empty (zero bytes content), but finalize() resolves normallyRequired handlingIf a glob pattern matches no files, no error is emitted and the archive is finalized with zero entries. This produces a valid but empty archive. Applications that expect at least one file must validate the 'entry' event count or pointer() > 0 after finalize() to detect unexpected empty archives.costlowin prodsilent failureusers seelost datavisibilitysilent - glob · glob-filesystem-errorerrorWhenreaddir-glob encounters a filesystem error (EACCES, ENOENT on root pattern dir)Throws
Emits 'error' event via onGlobError forwarding — same as archiver 'error' eventRequired handlingreaddir-glob errors (e.g. permission denied on the root glob directory, or invalid cwd path) are forwarded to the archiver 'error' event via the internal onGlobError handler. These errors terminate the glob traversal. Callers must have an 'error' event handler to catch these. Validate the cwd option is a real accessible directory before calling glob().costmediumin prodsilent failureusers seelost datavisibilitysilentSources[5] - symlink · symlink-zip-format-unsupportederrorWhensymlink() called on a zip-format archiver instanceThrows
Emits 'error' event with ArchiverError code='SYMLINKNOTSUPPORTED'Required handlingZIP format does not support symlinks. If symlink() is called on a zip archiver, it emits ArchiverError{ code: 'SYMLINKNOTSUPPORTED', message: 'support for symlink entries not defined by module' }. Only use symlink() with tar-format archives. Check archive format before calling symlink() or use a tar archive when symlinks are required.costlowin prodsilent failureusers seelost datavisibilitysilent - symlink · symlink-after-finalizeerrorWhensymlink() called after finalize() or abort()Throws
Emits 'error' event with ArchiverError code='QUEUECLOSED'Required handlingIf symlink() is called after finalize() or abort(), it emits ArchiverError{ code: 'QUEUECLOSED' }. The symlink entry is silently dropped.costlowin prodsilent failureusers seelost datavisibilitysilentSources[5] - symlink · symlink-missing-filepatherrorWhensymlink() called with non-string or empty filepath argumentThrows
Emits 'error' event with ArchiverError code='SYMLINKFILEPATHREQUIRED'Required handlingIf the first argument to symlink() is not a string or is an empty string, archiver emits ArchiverError{ code: 'SYMLINKFILEPATHREQUIRED', message: 'symlink filepath argument must be a non-empty string value' }. The symlink entry is silently dropped from the archive. Always validate the filepath argument (typeof === 'string' && length > 0) before calling symlink(), and have an 'error' event handler attached to surface validation failures.costlowin prodsilent failureusers seelost datavisibilitysilent - symlink · symlink-missing-targeterrorWhensymlink() called with non-string or empty target argumentThrows
Emits 'error' event with ArchiverError code='SYMLINKTARGETREQUIRED' (data includes filepath)Required handlingIf the second argument to symlink() is not a string or is an empty string, archiver emits ArchiverError{ code: 'SYMLINKTARGETREQUIRED', message: 'symlink target argument must be a non-empty string value', data: { filepath } }. The symlink entry is silently dropped. This commonly happens when caller code uses path.resolve() / readlinkSync() output without checking for empty results, or forgets the second argument entirely. Always validate the target string before calling symlink().costlowin prodsilent failureusers seelost datavisibilitysilent
Sources
Every postcondition cites at least one of these. Numbered to match the footnotes above.
- [1]github.com/archiverjs/node-archiverhttps://github.com/archiverjs/node-archiver/issues/181
- [2]npmjs.com/package/archiverhttps://www.npmjs.com/package/archiver
- [3]archiverjs.com/docs/archiverhttps://www.archiverjs.com/docs/archiver/
- [4]github.com/archiverjs/node-archiverhttps://github.com/archiverjs/node-archiver/issues/457
- [5]github.com/archiverjs/node-archiverhttps://github.com/archiverjs/node-archiver/blob/master/lib/core.js
- [6]github.com/archiverjs/node-archiverhttps://github.com/archiverjs/node-archiver/blob/master/lib/error.js
- [7]github.com/archiverjs/node-archiverhttps://github.com/archiverjs/node-archiver/issues/476
- [8]github.com/archiverjs/node-archiverhttps://github.com/archiverjs/node-archiver/issues/321
Need a different package?
Request a profile