avatar vian's notes

Learning in public, one post at a time

  • HOME
  • CATEGORIES
  • TAGS
  • ARCHIVES
  • ABOUT
Home Saving OpenCode Sessions After Laptop Swap
Post

Saving OpenCode Sessions After Laptop Swap

Posted Oct 12, 2026 Updated Oct 10, 2026
Terminal showing a SQL UPDATE remapping OpenCode session directories
Terminal showing a SQL UPDATE remapping OpenCode session directories
By Alvian
2 min read
Saving OpenCode Sessions After Laptop Swap
Saving OpenCode Sessions After Laptop Swap

The Empty Session List

My laptop got swapped recently, and the first thing I did on the new one was restore my ~/.local/share/opencode folder from backup. Inside was opencode.db — a 289 MB SQLite file I assumed held every session I’d ever run.

I opened OpenCode expecting my history. The list showed one session: the one I’d just started. My stomach did the thing.

The Data Was Never Gone

Before touching anything, I checked the source. The database was right there:

1
sqlite3 ~/.local/share/opencode/opencode.db ".tables"

163 rows in the session table. Titles, timestamps, token counts, the lot. The sessions hadn’t vanished — they just weren’t showing up.

That reframed the whole problem. This wasn’t recovery. It was a visibility bug, and the data was intact.

The Clue in One Column

Every old session carried the same field:

1
directory | /Users/pid-alvian

That was my old laptop’s account name. The new one is /Users/pid-user. Same home, different username.

OpenCode maps your home directory to a project it calls global, and the session list isn’t “all sessions” — it’s scoped to the directory you launched in. I proved it with two calls to the local server:

1
2
3
opencode serve --port 4099 &
curl -s "http://127.0.0.1:4099/session?directory=/Users/pid-alvian" | jq length  # 100
curl -s "http://127.0.0.1:4099/session?directory=/Users/pid-user"   | jq length  # 1

Same database, same sessions — filtered by a path that no longer existed. My history was there, just filed under a name that wasn’t mine anymore.

The Wrong Fix

My first instinct was OpenCode’s own export and import commands. Clean, supported, obviously correct.

It wasn’t. export returns one session at a time as {info, messages}, and it doesn’t include child sessions — the subagent runs spawned under a parent. Some of mine had three children each. Worse, importing re-creates sessions, which would have duplicated all 163 rows already sitting in the database.

The detour cost a few minutes, not my data. Before trusting the “official” path, look at what the data actually is.

The Fix: One Column

Only one table stored the path — session, columns directory and path. So I backed up the database first, then ran a single update:

1
2
3
UPDATE session
SET directory = '/Users/pid-user', path = 'Users/pid-user'
WHERE directory = '/Users/pid-alvian';

One statement. All 163 sessions remapped. The old directory filter returned zero, the new one returned everything, and the CLI listed all 27 top-level sessions.

What I’d Take From It

State keyed to a machine’s identity — a username, a home path — doesn’t travel when you move machines. The file copies over fine; the reference inside it doesn’t.

Two habits earned their keep here: check the data before assuming it’s lost, and reach for the smallest change that fixes it. The export/import detour would have worked, eventually, and quietly doubled my history. One column did the job without touching anything else.


Sources

  • OpenCode documentation
  • SQLite UPDATE statement
opencode tooling postmortem technical
This post is licensed under CC BY-NC 4.0 by the author.
Share

Recently Updated

  • Headroom, Round Two: Four Walls Between Me and a Working Token Saver
  • The Server Split That Almost Didn't Happen
  • I Opened My First Open Source PRs. None of Them Are Merged Yet.
  • Checking Upstream: What v0.5.50 Gained for 9router
  • The 403 That Wasn't: How Warp, 9router, and Cloudflare Masked Two Separate Failures

Trending Tags

9router technical tooling postmortem ade ai personal warp agents opencode

Contents

Further Reading

Aug 15, 2026

Your PID File Is a Lie: What Cloudflare Tunnel Taught Me About Process Supervision

Two ways to start the same server. One worked. The other gave me Bad Gateway. They ran the same code, listened on the same port, used the same config. The difference was invisible. Context I am ...

Aug 10, 2026

Headroom, Round Two: Four Walls Between Me and a Working Token Saver

Three days ago I wrote an autopsy about ripping a dead Headroom integration out of my 9router fork. The endpoint I was calling didn’t exist in the version I was running, the failure was swallowed s...

Aug 7, 2026

Debugging 9router Headroom: The Silent 404 That Masked a Version Mismatch

I found Headroom in a random LinkedIn post. It looked great — a compression proxy that sits between your app and the LLM providers, strips redundant context, saves tokens. The pitch was compelling....

© 2026 Alvian. Some rights reserved.

This blog is open source — view on GitHub

Using the Chirpy theme for Jekyll.

Trending Tags

9router technical tooling postmortem ade ai personal warp agents opencode