fix: avoid startup crash if unable to find default models (#3066)

Andrey Nering created

This can happen on edge cases when a models was removed from a provider
on Catwalk on Hyper.

Use the first model in the list instead crashing. This is not critical
to justify preventing Crush to start.

Change summary

internal/config/load.go      | 14 ++++++++++----
internal/config/load_test.go |  4 ++--
2 files changed, 12 insertions(+), 6 deletions(-)

Detailed changes

internal/config/load.go 🔗

@@ -545,8 +545,11 @@ func (c *Config) defaultModelSelection(knownProviders []catwalk.Provider) (large
 		}
 		defaultLargeModel := c.GetModel(string(p.ID), p.DefaultLargeModelID)
 		if defaultLargeModel == nil {
-			err = fmt.Errorf("default large model %s not found for provider %s", p.DefaultLargeModelID, p.ID)
-			return largeModel, smallModel, err
+			slog.Warn("Default large model %s not found for provider %s", p.DefaultLargeModelID, p.ID)
+			if len(providerConfig.Models) == 0 {
+				return largeModel, smallModel, fmt.Errorf("default large model %s not found for provider %s", p.DefaultLargeModelID, p.ID)
+			}
+			defaultLargeModel = &providerConfig.Models[0]
 		}
 		largeModel = SelectedModel{
 			Provider:        string(p.ID),
@@ -557,8 +560,11 @@ func (c *Config) defaultModelSelection(knownProviders []catwalk.Provider) (large
 
 		defaultSmallModel := c.GetModel(string(p.ID), p.DefaultSmallModelID)
 		if defaultSmallModel == nil {
-			err = fmt.Errorf("default small model %s not found for provider %s", p.DefaultSmallModelID, p.ID)
-			return largeModel, smallModel, err
+			slog.Warn("Default small model %s not found for provider %s", p.DefaultSmallModelID, p.ID)
+			if len(providerConfig.Models) == 0 {
+				return largeModel, smallModel, fmt.Errorf("default small model %s not found for provider %s", p.DefaultSmallModelID, p.ID)
+			}
+			defaultSmallModel = &providerConfig.Models[0]
 		}
 		smallModel = SelectedModel{
 			Provider:        string(p.ID),

internal/config/load_test.go 🔗

@@ -1148,7 +1148,7 @@ func TestConfig_defaultModelSelection(t *testing.T) {
 		_, _, err = cfg.defaultModelSelection(knownProviders)
 		require.Error(t, err)
 	})
-	t.Run("should error if model is missing", func(t *testing.T) {
+	t.Run("should not error if model is missing", func(t *testing.T) {
 		knownProviders := []catwalk.Provider{
 			{
 				ID:                  "openai",
@@ -1175,7 +1175,7 @@ func TestConfig_defaultModelSelection(t *testing.T) {
 		err := cfg.configureProviders(testStore(cfg), env, resolver, knownProviders)
 		require.NoError(t, err)
 		_, _, err = cfg.defaultModelSelection(knownProviders)
-		require.Error(t, err)
+		require.NoError(t, err)
 	})
 
 	t.Run("should configure the default models with a custom provider", func(t *testing.T) {