dagger/dagger · error
no LLM session active
Error message
no LLM session active
What it means
ExportChanges performs the ctrl+s action: exporting the workspace's pending overlay edits to the local Git workspace. It requires an active LLM session; when s.llm is nil there is nothing to export and the error is returned.
Source
Thrown at internal/cmd/dagger/llm.go:485
var buf strings.Builder
patchpreview.Summarize(idtui.NewOutput(&buf), entries, width)
return buf.String()
},
KeyMap: []key.Binding{
key.NewBinding(key.WithKeys("ctrl+s"), key.WithHelp("ctrl+s", "save")),
key.NewBinding(key.WithKeys("ctrl+u"), key.WithHelp("ctrl+u", "reset")),
},
})
return nil
}
// ExportChanges writes the workspace's pending overlay edits to its local Git
// workspace (Workspace.export), then refreshes the changes preview. It is the
// ctrl+s action; export fails clearly when the workspace cannot persist (a
// remote ref, a synthetic workspace, or a local dir with no Git root).
func (s *LLMSession) ExportChanges(ctx context.Context) error {
if s.llm == nil {
return fmt.Errorf("no LLM session active")
}
if err := s.llm.Workspace().Export(ctx); err != nil {
return err
}
// The exported edits now live on disk, so rebind the live workspace: the
// overlay the agent accumulated is now redundant with the files
// themselves, and carrying it forward would re-diff already-saved content
// as pending changes. Rebinding also drops it from the next save —
// portableID emits only the current binding. Export bumps the client's
// workspace read epoch, so reads after this point see the saved content
// rather than a snapshot cached earlier in the session. Sync eagerly so a
// failure surfaces here rather than corrupting later saves.
rebound, err := s.llm.WithWorkspace(s.dag.CurrentWorkspace()).Sync(ctx)
if err != nil {
return fmt.Errorf("rebind workspace after export: %w", err)
}
if err := s.updateLLM(rebound); err != nil {
return errView on GitHub (pinned to 82ba2681db)
Solutions
- Start the session (send a prompt via WithPrompt) before calling ExportChanges
- Guard the call: skip export when no session is active
- Re-create or reinitialize the session if it was reset unexpectedly
Example fix
// before
session.ExportChanges(ctx) // panics-free but errors: no LLM session active
// after
if session.LLM() != nil {
session.ExportChanges(ctx)
} Defensive patterns
Strategy: type-guard
Validate before calling
if session == nil || !session.Active() { return errors.New("start a prompt before exporting changes") } Type guard
func (s *LLMSession) HasLLM() bool { return s != nil && s.llm != nil } Try / catch
if err := session.ExportChanges(ctx); err != nil && err.Error() == "no LLM session active" { /* start session or skip */ } Prevention
- Track session lifecycle state in UI bindings
- Disable ctrl+s/export affordances until the first prompt
- Reset-dependent code should reinitialize before exporting
When it happens
Trigger: Calling LLMSession.ExportChanges before any prompt/session was started (s.llm == nil), e.g. via a keybinding or API call on a freshly constructed session.
Common situations: Calling ExportChanges in a script or TUI binding before the first prompt; resetting a session then attempting to export; UI state desync after session teardown.
Related errors
- attach llm workspace: %w
- attach llm workspace: unexpected result %T
- workspace recipe ID: %w
- rebind workspace after export: %w
- reset workspace: %w
AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05).
Data as JSON: /api/errors/679986215262d474.
Report an issue: GitHub.