JuliusBrussee/caveman · error

azure request has duplicate api-version values

Error message

azure request has duplicate api-version values

What it means

validateAzureRequest inspects Azure Foundry v1 inference routes and enforces at most one api-version query parameter, restricted to "v1" or "preview". Duplicate api-version values (repeated query keys) are ambiguous, so the request is rejected before building the upstream URL.

Solutions

  1. Remove duplicate api-version params so exactly one remains ("v1" or "preview" for Foundry routes)
  2. Fix URL-building code to append api-version only if not already present
  3. Use url.Values to construct the query string instead of string concatenation

Example fix

// before
u := base + "?api-version=v1"
u += "&api-version=preview"
// after
q := u.Query()
if q.Get("api-version") == "" {
	q.Set("api-version", "v1")
}
u.RawQuery = q.Encode()
Defensive patterns

Strategy: validation

Validate before calling

q := u.Query()
if len(q["api-version"]) > 1 {
	return errors.New("api-version may appear at most once")
}

Try / catch

u, err := adapter.ResolveUpstreamURL(ctx, req, route)
if err != nil && strings.Contains(err.Error(), "duplicate api-version") {
	// return 400 with guidance to dedupe query params
}

Prevention

When it happens

Trigger: Building an Azure OpenAI URL whose query string contains api-version twice, e.g. manually concatenated "...?api-version=v1&api-version=preview" or a template + override both appending api-version.

Common situations: String-concatenating query params onto a URL that already had api-version; deploying a route/template where a client SDK appends api-version on top of a configured one; copy-paste of example URLs retaining a second api-version.

Understand the failure class

Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/d76136f0cd989915. Report an issue: GitHub.

Appendix: source

Thrown at proxy/providers/azureopenai/azure_routing.go:42

	"2025-04-01-preview",
	"preview",
	"latest",
}

// ResolveUpstreamURL validates either the legacy deployment route or the
// current Foundry Models v1 inference route before resolving upstream.
func (a Adapter) ResolveUpstreamURL(ctx context.Context, req *http.Request, route providers.RouteContext) (*url.URL, error) {
	if err := validateAzureRequest(req.URL); err != nil {
		return nil, err
	}
	return a.Base.ResolveUpstreamURL(ctx, req, route)
}

func validateAzureRequest(u *url.URL) error {
	if foundryV1InferenceRoute(u.Path) {
		versions := u.Query()["api-version"]
		if len(versions) > 1 {
			return fmt.Errorf("azure request has duplicate api-version values")
		}
		if len(versions) == 1 && versions[0] != "v1" && versions[0] != "preview" {
			return fmt.Errorf("azure Foundry api-version %q is not supported", versions[0])
		}
		return nil
	}
	if !legacyChatCompletionsRoute(u.Path) {
		return fmt.Errorf("azure legacy inference path %q is not supported", u.Path)
	}
	versions := u.Query()["api-version"]
	if len(versions) > 1 {
		return fmt.Errorf("azure request has duplicate api-version values")
	}
	version := ""
	if len(versions) == 1 {
		version = versions[0]
	}
	if version == "" {

View on GitHub (pinned to 3ee70a1026)