different-ai/openwork · error

app.error_compact_no_session_id

Error message

app.error_compact_no_session_id

What it means

After confirming a client exists, compactCurrentSession resolves the session ID from the override argument or the currently selected session; if the trimmed result is empty it throws the localized 'app.error_compact_no_session_id'. The compact API needs an explicit session identifier and the UI cannot determine one.

Source

Thrown at apps/app/src/react-app/domains/session/sync/actions-store.ts:647

    const text = lastPromptSent().trim();
    if (!text) return;
    void sendPrompt({
      mode: "prompt",
      text,
      parts: [{ type: "text", text }],
      attachments: [],
    });
  }

  async function compactCurrentSession(sessionIdOverride?: string) {
    const c = options.client();
    if (!c) {
      throw new Error(t("app.error_not_connected"));
    }

    const sessionID = (sessionIdOverride ?? options.selectedSessionId() ?? "").trim();
    if (!sessionID) {
      throw new Error(t("app.error_compact_no_session_id"));
    }

    const visible = options.messages();
    if (!visible.length) {
      throw new Error(t("app.error_compact_empty"));
    }

    const model = options.selectedSessionModel();
    const startedAt = perfNow();
    const modelLabel = `${model.providerID}/${model.modelID}`;
    recordPerfLog(options.developerMode(), "session.compact", "start", {
      sessionID,
      messageCount: visible.length,
      model: modelLabel,
      variant: options.sanitizeModelVariantForRef(model, options.modelVariant()) ?? null,
    });

    try {

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Select a session in the UI (or pass a sessionIdOverride) before compacting.
  2. Gate the compact action on a non-empty selectedSessionId so it's disabled when nothing is selected.
  3. If a session is visually selected but the ID is empty, check selection state restoration after reconnect/delete.

Example fix

// before
await compactCurrentSession(); // no override, nothing selected
// after
const sid = selectedSessionId();
if (!sid) { showToast("Select a session first"); return; }
await compactCurrentSession(sid);
Defensive patterns

Strategy: validation

Validate before calling

const sid = (selectedSessionId() ?? "").trim();
if (!sid) {
  showToast("Select a session before compacting");
  return;
}
await compactCurrentSession(sid);

Type guard

function hasSessionId(s: { selectedSessionId?: string | null }): s is { selectedSessionId: string } {
  return typeof s.selectedSessionId === "string" && s.selectedSessionId.trim().length > 0;
}

Try / catch

try {
  await compactCurrentSession();
} catch (e) {
  if (e instanceof Error && e.message === "app.error_compact_no_session_id") {
    openSessionPicker();
    return;
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling compactCurrentSession() with no sessionIdOverride while options.selectedSessionId() returns null/undefined/whitespace — e.g. no session is selected, the session list hasn't loaded, or the selected session was deleted.

Common situations: Invoking compact programmatically or via a shortcut before any session is selected; stale UI after a session deletion; session ID lost after a reconnect that reset selection.

Related errors


AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/add907f30ea3d65c. Report an issue: GitHub.