@@ -778,12 +778,31 @@ func (a *sessionAgent) generateTitle(ctx context.Context, sessionID string, user
778778 if err == nil {
779779 slog.Info("generated title with large model")
780780 } else {
781− // Welp, the large model didn't work either.
781+ // Welp, the large model didn't work either. Use the default
782+ // session name and return.
782783 slog.Error("error generating title with large model", "err", err)
784+ saveErr := a.sessions.UpdateTitleAndUsage(ctx, sessionID, defaultSessionName, 0, 0, 0)
785+ if saveErr != nil {
786+ slog.Error("failed to save session title and usage", "error", saveErr)
787+ }
788+ return
789+ }
790+ }
791+
792+ if resp == nil {
793+ // Actually, we didn't get a response so we can't. Use the default
794+ // session name and return.
795+ slog.Error("response is nil; can't generate title")
796+ saveErr := a.sessions.UpdateTitleAndUsage(ctx, sessionID, defaultSessionName, 0, 0, 0)
797+ if saveErr != nil {
798+ slog.Error("failed to save session title and usage", "error", saveErr)
783799 }
800+ return
784801 }
785802
786− title := strings.ReplaceAll(resp.Response.Content.Text(), "\n", " ")
803+ // Clean up title.
804+ var title string
805+ title = strings.ReplaceAll(resp.Response.Content.Text(), "\n", " ")
787806 slog.Info("generated title", "title", title)
788807
789808 // Remove thinking tags if present.
@@ -808,10 +827,6 @@ func (a *sessionAgent) generateTitle(ctx context.Context, sessionID string, user
808827 }
809828 }
810829
811− if model == nil {
812− slog.Error("no model available for cost calculation")
813− return
814− }
815830 modelConfig := model.CatwalkCfg
816831 cost := modelConfig.CostPer1MInCached/1e6*float64(resp.TotalUsage.CacheCreationTokens) +
817832 modelConfig.CostPer1MOutCached/1e6*float64(resp.TotalUsage.CacheReadTokens) +