# Zip

Action `doc.zipper`

`action.zip`

Compress a file or folder into a `.zip` archive. The source comes from the upstream payload (typically `{{filePath}}`); the destination supports interpolation for dynamic names. Pairs naturally with Move File — archive a folder, then move the `.zip` somewhere.

## Ports

Direction | Name | Data Type | Description
--- | --- | --- | ---
Input | Input | File | Payload with the source file/folder path
Output | Output | Any | Payload with the created archive’s details

## Configuration

Field | Type | Default | Description
--- | --- | --- | ---
source | Variable picker | `{{filePath}}` | File or folder to compress. Pick the upstream variable that holds the path (e.g. `filePath`, or `item` from a For Each loop); blank falls back to `filePath`.
destination | Text | `{{directory}}/{{fileName}}.zip` | Where to write the `.zip`. Supports `{{var}}` interpolation.
compressionLevel | Dropdown | `fast` | Fast / Best / None. Advisory for now — reserved for a future release; all options currently produce a standard archive.
onExisting | Dropdown | `overwrite` | What to do when an archive already exists at the destination: `Overwrite` (replace), `Append` (add to the existing archive, creating it if absent), or `Keep both` (write to a numbered path). See Building one archive from many files.
createDirectories | Boolean | `true` | Create intermediate directories for the destination if they don’t exist.

## Output Variables

Merged onto the incoming payload. Both `archivePath` and `filePath` point at the new `.zip`, so it chains straight into Move File or another node with no remapping.

Variable | Type | Description
--- | --- | ---
archivePath | File | Absolute path to the created `.zip`.
filePath | File | Same as `archivePath` — for zero-remap chaining.
fileName | String | Name of the created archive.
itemCount | Number | Number of files compressed.
byteCount | Number | Size of the archive on disk, in bytes.
success | Boolean | `true` on success; `false` on a graceful failure (see below).

## Building one archive from many files

Set On existing → Append to accumulate many files into a single archive. This is what makes a fan-out collapse into one zip: wire the Unzip File outlet (or any per-file loop) into Zip with Append, and each file is added to the same archive in turn. Iterations run sequentially, so the appends are safe.

Two things to know:

- Use a fixed destination (e.g. `~/Desktop/photos.zip`), not the per-file default `{{fileName}}.zip` — otherwise each file targets its own archive and you get many zips instead of one.
- Append adds to whatever is already there, so it accumulates across runs too. To start fresh, delete (or move) the archive first — e.g. a Delete File before the loop.

## Error handling

Two tiers, by design. Everyday problems fail gracefully so a workflow can branch on them; only genuine safety violations hard-fail.

Graceful — `success: false`

Returns a normal payload with `success: false` and an `error` reason — never throws, so the run continues and a Condition can route the failure.

- `no_input_path` — no source path was provided or resolved.
- `source_not_found` — the source path is valid but nothing exists there.

Hard fail — stops the run

Throws and marks the node failed (the red banner) only for real safety violations:

- `protected location` — the source or archive destination resolves into a denied path (`~/Library` internals, `~/.ssh`, system roots) or uses `..` traversal. iCloud Drive and other cloud folders are allowed.
- `compression failed` — the underlying `ditto` step exits non-zero (e.g. the disk is full).

## Example

Archive a project folder, then move the zip to an archive directory: