JuliusBrussee/caveman · error
ambiguous escaped path sequence %s
Error message
ambiguous escaped path sequence %s
What it means
The path (decoded or raw) contains an ambiguous percent-escape (%2f, %5c, or %2e) that could decode into a separator or dot segment after another proxy hop, changing route identity; the gateway rejects it.
Source
Thrown at proxy/providers/openaicompat/openaicompat.go:330
func validatePathComponents(path, rawPath string) error {
if strings.Contains(path, `\`) {
return fmt.Errorf("backslash is not allowed in path")
}
segments := strings.Split(path, "/")
for i, segment := range segments {
if segment == "" && i > 0 && i < len(segments)-1 {
return fmt.Errorf("repeated path separators are not allowed")
}
if segment == "." || segment == ".." {
return fmt.Errorf("dot segments are not allowed in path")
}
}
// URL.Path is decoded by net/url while RawPath retains a valid escaped
// spelling. Reject separators, backslashes, and dot bytes in either form so
// a path cannot change route identity after another decoder or proxy hop.
for _, escape := range []string{"%2f", "%5c", "%2e"} {
if strings.Contains(strings.ToLower(path), escape) || strings.Contains(strings.ToLower(rawPath), escape) {
return fmt.Errorf("ambiguous escaped path sequence %s", escape)
}
}
return nil
}
func parseBaseURL(raw, provider string) (*url.URL, error) {
if strings.TrimSpace(raw) == "" {
return nil, fmt.Errorf("provider %q has no configured upstream URL", provider)
}
u, err := url.Parse(strings.TrimSpace(raw))
if err != nil {
return nil, err
}
if u.Scheme != "http" && u.Scheme != "https" {
return nil, fmt.Errorf("provider %q upstream URL scheme %q is not allowed", provider, u.Scheme)
}
if !u.IsAbs() || u.Host == "" || u.Hostname() == "" {
return nil, fmt.Errorf("provider %q upstream URL must be an absolute URL with a host", provider)View on GitHub (pinned to 5184b3d11a)
Solutions
- Percent-encode literal characters as their safe equivalents or avoid them entirely
- Remove double-encoding introduced by intermediate proxies
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at proxy/providers/openaicompat/openaicompat.go:287 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of JuliusBrussee/caveman@5184b3d11a (2026-08-18).
Data as JSON: /api/errors/7aac0ae3c29a1995.
Report an issue: GitHub.