can1357/oh-my-pi · warning · Error
Collab replica activation was cancelled
Error message
Collab replica activation was cancelled
What it means
After downloading the host's snapshot and writing it to a replica session file, the guest resumes it via ctx.session.switchSession(replicaPath, { preserveLocalCwd: true }). switchSession returned false, meaning the interactive session refused/aborted the switch (typically the user cancelled a confirmation prompt). The guest throws so the join is not half-applied: no snapshot state, UI, or agent mirror is adopted.
Source
Thrown at packages/coding-agent/src/collab/guest.ts:444
this.#armSnapshotProgressTimer();
}
return complete;
}
/** Write the accumulated welcome snapshot to the replica file and (re)load it through the resume machinery. */
async #finalizeSnapshot(): Promise<void> {
const pending = this.#pendingSnapshot;
this.#pendingSnapshot = null;
this.#clearSnapshotProgressTimer();
if (!pending || this.#left) return;
const replicaPath = path.join(getConfigRootDir(), "collab", `${this.#roomId}.jsonl`);
const lines = [pending.header, ...pending.entries].map(entry => JSON.stringify(entry)).join("\n");
await Bun.write(replicaPath, `${lines}\n`);
// Resume through AgentSession without adopting the host's cwd.
const switched = await this.#ctx.session.switchSession(replicaPath, { preserveLocalCwd: true });
if (switched === false) {
throw new Error("Collab replica activation was cancelled");
}
this.#clearTransientUi();
this.#clearAgentMirror();
this.state = pending.state;
reconcileGuestSnapshotHostState(this.#ctx, pending.state.isStreaming);
this.#applyHostState(pending.state);
this.#ctx.resetObserverRegistry();
this.#applyAgentSnapshots(pending.agents);
this.#ctx.syncRunningSubagentBadge();
this.#assistantStreamSynced = false;
setSessionTerminalTitle(pending.state.sessionName ?? pending.header.title, pending.state.cwd);
this.#ctx.chatContainer.disposeChildren();
await this.#ctx.renderInitialMessages({ clearTerminalHistory: true });
await this.#ctx.reloadTodos();
this.#updateStatusSegment();
this.#readOnly = pending.readOnly;
this.#welcomed = true;
const suffix = this.#readOnly ? " (read-only)" : "";View on GitHub (pinned to 9690622007)
Solutions
- Retry the join and accept the session-switch prompt when it appears.
- Finish or abandon the current session first, then re-join the room so no confirmation is needed.
- Inspect the replica session file written to the temp/replica path if the switch keeps failing despite accepting the prompt.
- If embedding the guest non-interactively, provide a switchSession implementation that does not require user confirmation, or handle the cancelled case by keeping the local session.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await guest.join(link);
} catch (err) {
if (err instanceof Error && err.message.includes("cancelled")) {
ui.info("Join aborted — the session switch was cancelled; current session unchanged.");
return;
}
throw err;
} Prevention
- Accept the session-switch confirmation prompt when joining.
- Join from a quiet session state (not mid-stream) to minimize prompting.
- Communicate to users that joining replaces the current session view.
When it happens
Trigger: A guest joining a room when the interactive session prompts to switch away from the current session and the user dismisses/cancels it; switchSession failing internally and reporting false (e.g. replica file rejected by the session loader).
Common situations: Guest already has an active session with unsaved context and cancels the 'switch session?' dialog during join; a corrupted replica file causes the session manager to bail; joining from a context (RPC mode, script) where interactive switching is not possible.
Related errors
- Room key must be ${ROOM_KEY_BYTES} bytes, got ${raw.byteLeng
- error
- error
- error
- collab.webUrl must start with http:// or https://
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1cbf33bb4377570e.
Report an issue: GitHub.