googleapis/mcp-toolbox · error

resolved path %q escapes base path %q

Error message

resolved path %q escapes base path %q

What it means

Even after rejecting dot segments, the final URL (BaseURL resolved with the relative path) is checked to ensure its path stays within the base URL's path prefix. This error means the resolved path escaped the configured base path scope, so the request would target an endpoint outside what the tool was configured to allow.

Source

Thrown at internal/tools/http/http.go:223

	// Reject dot segments before resolution
	for _, segment := range strings.Split(relParsedURL.Path, "/") {
		if segment == ".." {
			return "", fmt.Errorf("path cannot contain dot segments (..)")
		}
	}

	// Create URL based on BaseURL and Path
	// Attach query parameters
	parsedURL := baseParsedURL.ResolveReference(relParsedURL)

	// Verify final path stays within base path scope
	basePath := baseParsedURL.Path
	finalPath := parsedURL.Path
	if basePath != "/" {
		requiredPrefix := strings.TrimSuffix(basePath, "/") + "/"
		if finalPath != basePath && !strings.HasPrefix(finalPath, requiredPrefix) {
			return "", fmt.Errorf("resolved path %q escapes base path %q", finalPath, basePath)
		}
	}

	// Get existing query parameters from the URL
	queryParameters := parsedURL.Query()
	for key, value := range defaultQueryParams {
		queryParameters.Add(key, value)
	}
	parsedURL.RawQuery = queryParameters.Encode()

	// Set dynamic query parameters
	query := parsedURL.Query()
	for _, p := range queryParams {
		v, ok := paramsMap[p.GetName()]
		if !ok || v == nil {
			if !p.GetRequired() {
				// If the param is not required AND
				// Not provodid OR provided with a nil value

View on GitHub (pinned to 8cc6e09de2)

Solutions

  1. Make the relative path consistent with the base path prefix (e.g. pass '/items' to hit https://host/api/v1/items)
  2. Fix the tool's BaseURL configuration so its path matches the actual API root the paths are written for
  3. Inspect the resolved path in the error message and adjust it so it begins with the base path

Example fix

// before (base: https://host/api/v1)
path: /other/endpoint
// after
path: /api-prefix-adjusted/endpoint  // or fix BaseURL to https://host/
Defensive patterns

Strategy: validation

Validate before calling

base, _ := url.Parse(baseURL)
rel, _ := url.Parse(pathParam)
resolved := base.ResolveReference(rel)
if !strings.HasPrefix(strings.TrimSuffix(base.Path, "/")+"/", resolved.Path) && resolved.Path != base.Path {
    // only flag when resolved escapes; correct check:
}
required := strings.TrimSuffix(base.Path, "/") + "/"
if resolved.Path != base.Path && !strings.HasPrefix(resolved.Path, required) {
    return fmt.Errorf("path %q escapes base path %q", resolved.Path, base.Path)
}

Type guard

func staysWithinBase(baseURL, p string) bool {
    base, _ := url.Parse(baseURL)
    rel, err := url.Parse(p)
    if err != nil { return false }
    out := base.ResolveReference(rel)
    required := strings.TrimSuffix(base.Path, "/") + "/"
    return out.Path == base.Path || strings.HasPrefix(out.Path, required)
}

Prevention

When it happens

Trigger: The base URL has a non-root path (e.g. https://host/api/v1) and the relative path resolves to something outside it — e.g. path '/other' resolves to https://host/other, or an encoded/absolute-style path replaces the base path during ResolveReference.

Common situations: Config authors set BaseURL including '/api/v1' but tool callers pass paths assuming the host root; paths beginning with '//' or containing encoded traversal slipping past earlier checks; misconfigured base path vs. documented API prefix mismatch.

Related errors


AI-assisted analysis of googleapis/mcp-toolbox@8cc6e09de2 (2026-09-05). Data as JSON: /api/errors/6f6ce0acb13c11eb. Report an issue: GitHub.