JuliusBrussee/caveman · error
compat route path rejected
Error message
compat route path rejected: %w
What it means
validateCompatPath applies strict component validation to any path under /compat/ and wraps the underlying cause with 'compat route path rejected'. It exists so a path cannot change route identity after decoding by another proxy hop. The wrapped cause is one of: backslash, repeated separators, dot segments, or ambiguous escapes.
Solutions
- Remove backslashes, empty inner segments, and dot segments from the request path
- URL-encode payloads so no %2f, %5c, or %2e appear in the path (put variable data in the body or query where allowed)
- Fix the upstream BaseURL in config if it contains such components
- Send the request without a rawPath escape spelling that differs from the decoded path
Example fix
// before GET /compat/openai/v1/chat/../completions // after GET /compat/openai/v1/chat/completions
Defensive patterns
Strategy: validation
Validate before calling
func safeCompatPath(p string) error {
if strings.Contains(p, "\\") || strings.Contains(p, "..") || strings.Contains(p, "//") {
return fmt.Errorf("unsafe path %q", p)
}
return nil
} Try / catch
if err := ValidateRequestPath(req.URL); err != nil {
log.Warnf("rejected compat path: %v", err)
http.Error(w, "invalid path", http.StatusBadRequest)
return
} Prevention
- Never build compat URLs by string concatenation of untrusted segments
- Keep ids path-safe (alphanumeric, dash, underscore) or move them to the body
- Test clients against ValidateRequestPath in CI
When it happens
Trigger: Requesting any /compat/... path containing a backslash, '//' inside the path, '.'/'..' segments, or %2f/%5c/%2e escapes in Path or RawPath; configuring an upstream BaseURL whose path contains such components (via parseBaseURL's validation).
Common situations: Clients URL-encoding slashes in model names or resource ids; buggy client code double-encoding paths; misconfigured base URLs containing '..' or '//'; security scanners probing path traversal.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- ambiguous escaped path sequence
- backslash is not allowed in path
- compat upstream forward_headers
- header cannot be forwarded
- caveman-code: path escapes the workspace
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/eb6e52636bab8dad.
Report an issue: GitHub.
Appendix: source
Thrown at proxy/providers/openaicompat/openaicompat.go:482
// Gateways call this with the original URL (including RawPath), while the
// adapter MatchRoute/ResolveUpstreamURL checks provide a second fail-closed
// boundary for direct callers.
func ValidateRequestPath(u *url.URL) error {
if u == nil {
return fmt.Errorf("request URL is missing")
}
if !strings.HasPrefix(u.Path, "/compat/") {
return nil
}
return validateCompatPath(u.Path, u.RawPath)
}
func validateCompatPath(path, rawPath string) error {
if !strings.HasPrefix(path, "/compat/") {
return nil
}
if err := validatePathComponents(path, rawPath); err != nil {
return fmt.Errorf("compat route path rejected: %w", err)
}
return nil
}
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 escapedView on GitHub (pinned to 3ee70a1026)