chenhg5/cc-connect · warning

opencode: delete session %s: %w: %s

Error message

opencode: delete session %s: %w: %s

What it means

DeleteSession runs `opencode session delete <id>` in the agent's workDir; on failure it wraps the exec error plus the command's combined stdout/stderr as `opencode: delete session <id>: <err>: <output>`. The appended output is opencode's own diagnostic explaining why the delete failed (e.g. session not found).

Source

Thrown at agent/opencode/opencode.go:505

	cmd := a.cmd
	workDir := a.workDir
	a.mu.RUnlock()
	return listOpencodeSessions(cmd, workDir)
}

func (a *Agent) Stop() error { return nil }

// DeleteSession implements core.SessionDeleter via `opencode session delete <id>`.
func (a *Agent) DeleteSession(_ context.Context, sessionID string) error {
	a.mu.RLock()
	cmd := a.cmd
	workDir := a.workDir
	a.mu.RUnlock()

	c := exec.Command(cmd, "session", "delete", sessionID)
	c.Dir = workDir
	if out, err := c.CombinedOutput(); err != nil {
		return fmt.Errorf("opencode: delete session %s: %w: %s", sessionID, err, strings.TrimSpace(string(out)))
	}
	return nil
}

// -- ModeSwitcher --

func (a *Agent) SetMode(mode string) {
	a.mu.Lock()
	defer a.mu.Unlock()
	a.mode = normalizeMode(mode)
	slog.Info("opencode: mode changed", "mode", a.mode)
}

func (a *Agent) GetMode() string {
	a.mu.Lock()
	defer a.mu.Unlock()
	return a.mode
}

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Read the embedded output string for the concrete cause; if the session is already gone, treat the delete as idempotent and ignore the error.
  2. Confirm the id exists first: run `opencode session list` before deleting.
  3. Fix ownership/permissions of opencode's session data directory for the daemon user.
  4. Reproduce manually: `cd <workDir> && opencode session delete <id>` and inspect the combined output.

Example fix

// before
if err := agent.DeleteSession(ctx, id); err != nil {
    return err // fails hard on already-deleted sessions
}

// after
if err := agent.DeleteSession(ctx, id); err != nil {
    if strings.Contains(err.Error(), "not found") {
        return nil // idempotent delete
    }
    return err
}
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm the session still exists before deleting
sessions, err := agent.ListSessions(ctx)
if err == nil && !containsSession(sessions, sessionID) {
    return nil // nothing to delete
}

Try / catch

if err := agent.DeleteSession(ctx, id); err != nil {
    if strings.Contains(err.Error(), "not found") {
        return nil // idempotent: already deleted
    }
    return fmt.Errorf("delete session failed, see embedded CLI output: %w", err)
}

Prevention

When it happens

Trigger: Deleting a session id that no longer exists (already deleted or a stale ListSessions result); opencode exits non-zero due to a corrupt session store, permission problems on its data directory, or a CLI version whose `session delete` subcommand changed.

Common situations: Cleaning up sessions already removed by opencode or manual storage cleanup; cc-connect running as a different user than the one who created the sessions (data-dir ownership); CLI upgrade changing subcommand behavior.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/74c305513ca5a2f8. Report an issue: GitHub.