fix(providers): validate metadataPath has a leading slash

fetchModelMetadata (provider_openai.go) builds its request URL by plain
string concatenation, a.baseURL+a.metadataPath. A metadataPath missing
its leading slash would silently glue onto baseURL's own path with no
separator (e.g. "http://host:1234api/v0/models"), a malformed URL that
only ever surfaced as a confusing runtime fetch failure. buildAdapters
now rejects a non-empty metadataPath without a leading "/" at
construction, naming the provider, the same fail-fast treatment every
other malformed config value already gets. Empty (the default) is
always valid. Folded review minor.
This commit is contained in:
2026-08-22 02:12:14 +01:00
parent 82dcaa5309
commit 962f5eeeed
2 changed files with 41 additions and 0 deletions
+18
View File
@@ -708,6 +708,24 @@ func TestBuildAdapters(t *testing.T) {
}
})
t.Run("bad: metadataPath without a leading slash is a constructor error (review fix)", func(t *testing.T) {
cfg := &Config{Providers: map[string]*ProviderConfig{
"lmstudio": {Type: "openai", MetadataPath: "api/v0/models"},
}}
if _, err := buildAdapters(cfg); err == nil {
t.Error("want an error for a metadataPath missing its leading slash")
}
})
t.Run("good: empty metadataPath is valid (feature disabled)", func(t *testing.T) {
cfg := &Config{Providers: map[string]*ProviderConfig{
"p1": {Type: "openai", APIKey: "sk-test"},
}}
if _, err := buildAdapters(cfg); err != nil {
t.Errorf("buildAdapters: %v, want no error for an empty metadataPath", err)
}
})
t.Run("good: explicit base URL trailing slash trimmed", func(t *testing.T) {
cfg := &Config{Providers: map[string]*ProviderConfig{
"p1": {Type: "openai", BaseURL: "https://custom.example.com/", APIKey: "sk-test"},