Skip to content

session.shutdown event should persist the reason from SessionEndHookInput #2852

@d0d1

Description

@d0d1

Problem

The runtime internally tracks session end reason via SessionEndHookInput.reason, but the session.shutdown event persisted to events.jsonl only records shutdownType: "routine" | "error". That collapses several distinct non-error causes into the single label "routine" and makes post-hoc diagnosis of session lifecycle incidents much harder than it needs to be.

From the installed 1.0.32 type definitions:

// sdk/index.d.ts
export declare interface SessionEndHookInput extends BaseHookInput {
    reason: "complete" | "error" | "abort" | "timeout" | "user_exit";
    finalMessage?: string;
    error?: Error;
}

// sdk/index.d.ts
shutdown(shutdownType?: "routine" | "error", errorReason?: string): void;

// copilot-sdk/generated/session-events.d.ts
data: {
    shutdownType: "routine" | "error";
    errorReason?: string;
    // ... usage metrics
}

So the runtime appears to have more granular reason information available internally, but the persisted shutdown event does not keep it.

Concrete impact

In one 1.0.32/Linux session, I observed two session.shutdown events with shutdownType: "routine" that had materially different provenance:

Shutdown Provenance visible from nearby events
1st preceded by an abort event with reason: "user initiated", resumed 18 seconds later
2nd no preceding abort, interrupted active tool execution, bash subprocess received SIGTERM / exit 143 163 ms later, resume happened 2h 44m later

At the session.shutdown event level, those two cases are indistinguishable even though the surrounding event stream shows they are not the same kind of lifecycle transition.

Context for the second shutdown

Single incident; not claiming a reproducible bug. Parameters at the time of the disruptive shutdown:

Metric Value
Copilot CLI 1.0.32
OS Linux
Session age 6h 12m 49.578s
Time since last user message 5h 24m 08.244s
events.jsonl size through shutdown line 45,016,499 bytes / 11,691 lines
task tool launches before shutdown 40
Cumulative API duration 38,889,407 ms (~10.8h)

I am not claiming the shutdown itself was necessarily a bug. It may have been policy, host lifecycle, resource pressure, or something else. The issue here is that the persisted shutdown event does not retain enough reason information to let users or maintainers tell which.

Request

Please persist the internal session-end reason (or equivalent) into session.shutdown events. Even a small additive field would help a lot, for example:

data: {
    shutdownType: "routine" | "error";
    reason?: "complete" | "abort" | "timeout" | "user_exit";
    errorReason?: string;
}

If the runtime can distinguish other routine-shutdown causes such as external signal receipt or platform/session eviction, a richer optional field would be even better. But even persisting the existing SessionEndHookInput.reason values would be a meaningful improvement.

Why this matters

This would make it much easier to triage session-lifecycle issues without reproducing them live, including cases that currently look similar in raw logs but may have very different causes.

Related issues

Environment

  • Copilot CLI 1.0.32
  • Node.js v24.11.1
  • Linux x86_64

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:sessionsSession management, resume, history, session picker, and session state
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions