Skip to content

migration: one-time V1-to-V2 session import misses sessions and messages created by V1 afterwards #58840

Closed as duplicate

Description

@desaiamogh

Summary

The V1→V2 session migration is a one-time import: after it completes, any sessions and messages created by a still-installed V1 app (e.g. the V1 desktop app) are never imported, so they are invisible to V2. This makes restored desktop tabs point at sessions the V2 server cannot find ("This session cannot be found / this tab points to a session that no longer exists on this server"), and it silently truncates the transcripts of sessions that were migrated before being continued in V1.

Environment

  • opencode version: 2.1.4 (V2 server/desktop; bundled CLI 2.1.4). Previously V1 desktop app running server v1.19.4.
  • OS: Windows_NT 10.0.26200 (win32 x64)
  • Terminal: N/A — OpenCode desktop app
  • Shell: cmd.exe
  • Install/channel: desktop app, latest channel
  • Active plugins: none found in config

Reproduction

  1. Have the V1 desktop app installed (its server writes the legacy session, message, part tables in ~/.local/share/opencode/opencode.db). Also start a V2 binary (CLI 2.1.4) once — the one-time migration runs and marks itself completed (kv key migration.v1-v2 = {"phase":"completed"}).
  2. Keep using the V1 desktop app for a while: create new sessions and continue old ones. These writes go to the legacy tables only.
  3. Uninstall the V1 desktop and install the V2 desktop (2.1.4). The V2 server serves sessions only from the new session_v2 / session_message tables.
  4. On first launch the desktop restores its previous tab layout (kept in %APPDATA%\ai.opencode.desktop, which the uninstaller does not remove). Tabs pointing at V1-created sessions fail with "This session cannot be found — this tab points to a session that no longer exists on this server".

Expected Behavior

V2 should surface sessions/messages written by V1 after the one-time import — e.g. re-run the legacy import incrementally at server start (import legacy rows missing from session_v2/session_message), or merge both tables when serving. The V1→V2 migration guide states non-API V1 behavior is intended to remain compatible; sessions created right before upgrading are effectively lost from the UI otherwise.

Actual Behavior

Observed on this machine (data was recovered manually; nothing was actually deleted):

  • 5 sessions created by the V1 app after the import had completed were present in the legacy session table (with all messages in message/part) but absent from session_v2, so GET /api/session did not list them and GET /api/session/{id} 404'd. Sizes: 712, 104, 80, 18 and 2 messages respectively (916 total).
  • 1 already-migrated session continued in V1 lost visibility of ~380 messages appended after the import: the API served only its first 30 messages even though the legacy tables held ~410.
  • The kv table contains migration.v1-v2 = {"phase":"completed"} with a timestamp between the two batches, which is why the later batch was never imported.

Workaround used (documenting for others hitting this): copy the legacy session rows into session_v2 (NULL for v2-only columns, resume_attempts=0), and transform message+part rows into session_message (role → type, legacy order → seq, state.output → state.content[0].text, state.error string → state.error = {type: "tool.execution", message}, callID→id, tool→name, part-level metadata→providerState, drop step-start/step-finish/patch parts but keep snapshot.start/snapshot.end/snapshot.files, drop title/time from state, meta.variant → model.variant defaulting to default). This reproduces what the one-time importer produces (verified byte-identical against all 650 messages it had already imported on this machine).

Additional Context

  • The V1 desktop and V2 desktop share the same data directory (~/.local/share/opencode/), including opencode.log, so the two server versions log side by side; V1 runs logged version=1.19.4 on session creation while V2 sessions log version=2.1.4.
  • Uninstalling the V1 desktop does not clear %APPDATA%\ai.opencode.desktop (tab/window state), which is why stale tabs referencing now-invisible sessions surface immediately after upgrading.
  • Recovery was verified end-to-end via the V2 API (all 916 messages served and rendered correctly, including tool parts, reasoning, snapshots, tokens, errored and aborted tools).
  • Frequency: deterministic for any V1 session/message created after the one-time import has run.

Activity

  1. opencode-agent commented on Oct 25, 2026

    @opencode-agent
    Contributor

    Thanks for the very thorough report and for writing down the manual recovery steps.

    I think this is a duplicate of #50130: the V1→V2 import runs only once, so sessions a V1 client creates after migration.v1-v2 is marked completed never get imported, and desktop tabs pointing at them show "no longer exists on this server". The truncated transcript for the session you kept using in V1 is tracked separately in #57000.

    Possible duplicates and related issues, ordered by likelihood:

    The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different. Your field-mapping notes and the byte-identical check against the importer's output would be useful in #50130 and #57000.

  2. opencode-agent commented on Oct 26, 2026

    @opencode-agent
    Contributor

    We didn't hear back, so I'm closing this as a duplicate of #50130. It covers V1 sessions created after migration.v1-v2 was marked completed, which are never imported. The missing messages in your already-migrated session are tracked in #57000, and open PR #54272 would import V1 sessions created after the migration finished.

    Please follow those issues for updates. Your field mappings and the byte-identical check against the importer's output would help there, so consider adding them. If your problem turns out to be different, reply here and we can reopen this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions