How to Update Paperclip
There are two ways to update Paperclip: the quick way using npx, or the manual way by checking out a specific git tag over SSH.
Method 1: Quick update with npx
The easiest way to update. This pulls and runs the latest published version directly — no git checkout or pnpm install needed.
1. SSH into the server
ssh paperclip
2. Navigate to the repo
cd ~/paperclip
3. Run the latest version
npx paperclipai@latest run
This downloads and executes the latest release in one step. It handles dependency resolution automatically.
4. Verify
Check that the server starts cleanly. Look for Server listening on 0.0.0.0:3100 in the output, or from another terminal:
curl -s http://localhost:3100/api/health
Method 2: Manual update to a specific tagged release over SSH
Use this when you want to pin to a specific version rather than always pulling the latest.
1. SSH into the server
ssh paperclip
2. Navigate to the repo
cd ~/paperclip
3. Check your current version
git describe --tags
4. Fetch new tags from origin
git fetch origin --tags
5. Checkout the target release
Replace the tag with your target version:
git checkout v2026.325.0
You'll see a "detached HEAD" message — that's expected and correct for running a tagged release.
6. Install dependencies
pnpm install
7. Restart Paperclip
If running via systemd (survives reboots)
sudo systemctl restart paperclip
If running via tmux
Reattach to your session:
tmux attach
Stop the running process with Ctrl+C, then restart:
pnpm paperclipai run
Detach when it's up: Ctrl+B, then d.
If there's no existing tmux session:
tmux new
cd ~/paperclip
pnpm paperclipai run
8. Verify
git describe --tags
systemd
sudo systemctl status paperclip
journalctl -u paperclip -f
tmux
Output is right in front of you in the tmux session. Look for Server listening on 0.0.0.0:3100. You can also check from another terminal:
curl -s http://localhost:3100/api/health
Press Ctrl+C to exit log tails once you've confirmed it's running cleanly.
9. Sanity check: Node path (systemd only)
If you've ever updated Node via nvm, make sure the service file still points to the right version:
which node
grep PATH /etc/systemd/system/paperclip.service
If the paths don't match, update the service file, then:
sudo systemctl daemon-reload
sudo systemctl restart paperclip
This doesn't apply to tmux — tmux inherits your shell environment, so it picks up the current Node automatically.
Diagnostics
Live logs
systemd:
journalctl -u paperclip -f
tmux: Reattach to the session — logs stream to stdout directly:
tmux attach
Historical logs
systemd:
journalctl -u paperclip -n 200 --no-pager # last 200 lines
journalctl -u paperclip --since "1 hour ago" # time-based filter
journalctl -u paperclip --since "2026-03-25" # since a specific date
tmux: Scroll up in the tmux session with Ctrl+B, then [, then arrow keys or PgUp. Press q to exit scroll mode.
App log file
tail -f ~/paperclip.log
Warning: paperclip.log can contain stale output from prior runs. After a systemd restart, prefer journalctl for fresh logs. In tmux, the live output in your session is always current.
Service status
systemd:
sudo systemctl status paperclip
tmux:
tmux ls # is the session still alive?
curl -s http://localhost:3100/api/health # is the app responding?
Check what systemd is actually running
grep ExecStart /etc/systemd/system/paperclip.service
cat /etc/systemd/system/paperclip.service.d/override.conf # systemd overrides
Health check
curl -s http://localhost:3100/api/health
Disk usage (backups can fill the disk)
df -h
du -sh ~/.paperclip/instances/default/data/backups/
Troubleshooting
EBADF: bad file descriptor, read (systemd only)
If you see this after a systemd restart, it means a process (usually tsx watch in dev mode) is trying to read stdin, which doesn't exist under systemd. This won't happen in tmux. Fix:
sudo systemctl edit paperclip
Add:
[Service]
StandardInput=null
Then:
sudo systemctl daemon-reload
sudo systemctl restart paperclip
Local changes blocking checkout
If git checkout fails due to uncommitted changes:
git stash
git checkout v2026.325.0
git stash pop # only if you want the changes back
Confirming a healthy startup
Whether you're reading journalctl or watching tmux output, a good boot looks like:
9 passed/All checks passed!Embedded PostgreSQL readyMigrations already appliedServer listening on 0.0.0.0:3100
If you see ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL or ELIFECYCLE, scroll up — the root cause is always above those lines.
Notes
- Detached HEAD is fine. Tagged releases aren't branches. You're pinned to an exact commit.
- systemd: use
journalctlafter a restart, nottail ~/paperclip.log. The log file may still show output from the previous (crashed) run, which is misleading. - tmux won't survive a reboot. If your EC2 instance restarts, you'll need to manually start a new tmux session and run Paperclip again. systemd handles this automatically.
- Backup retention is built-in now. As of recent releases, the server reports
DB Backup enabled (every 60m, keep 30d)at startup. Your cron job for pruning old backups is a secondary safety net. paperclipai runauto-detects dev vs production mode. On a headless server via systemd it should land on the right mode. If it enters dev mode unexpectedly, checkpnpm paperclipai run --helpfor a production flag.