{"record":{"id":"a231438c708e51c4","repo":"googleapis/mcp-toolbox","slug":"error-parsing-base-url-s","errorCode":null,"errorMessage":"error parsing base URL: %s","messagePattern":"error parsing base URL: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/tools/http/http.go","lineNumber":191,"sourceCode":"\t\t\t\treturn \"\"\n\t\t\t}\n\t\t\treturn url.QueryEscape(fmt.Sprintf(\"%v\", v))\n\t\t},\n\t}\n\n\ttempl, err := template.New(\"url\").Funcs(funcMap).Parse(path)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error parsing URL: %s\", err)\n\t}\n\tvar templatedPath bytes.Buffer\n\terr = templ.Execute(&templatedPath, pathParamsMap)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error replacing pathParams: %s\", err)\n\t}\n\n\tbaseParsedURL, err := url.Parse(baseURL)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error parsing base URL: %s\", err)\n\t}\n\tif baseParsedURL.Scheme == \"\" || baseParsedURL.Host == \"\" {\n\t\treturn \"\", fmt.Errorf(\"base URL must include scheme and host\")\n\t}\n\n\trelativePath := templatedPath.String()\n\trelParsedURL, err := url.Parse(relativePath)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"error parsing URL path: %s\", err)\n\t}\n\tif relParsedURL.Scheme != \"\" || relParsedURL.Host != \"\" || relParsedURL.User != nil {\n\t\treturn \"\", fmt.Errorf(\"path must be relative and cannot override base host\")\n\t}\n\n\t// Reject dot segments before resolution\n\tfor _, segment := range strings.Split(relParsedURL.Path, \"/\") {\n\t\tif segment == \"..\" {\n\t\t\treturn \"\", fmt.Errorf(\"path cannot contain dot segments (..)\")","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/tools/http/http.go#L173-L209","documentation":"getURL parses the source's HttpBaseURL() with net/url.Parse before resolving the relative path. If the base URL string is not a parseable URL, the parse error is wrapped as \"error parsing base URL\" and Invoke fails with an agent error.","triggerScenarios":"The http source's baseUrl config value is malformed — contains spaces, control characters, or invalid percent-encodings like \"http://api.example.com/%zz\" — causing url.Parse to fail during Invoke.","commonSituations":"Env-var-substituted base URLs with stray whitespace or quotes; truncated URLs in YAML; invalid percent-encoding after string interpolation.","solutions":["Fix the source's \"baseUrl\" in tools.yaml so it is a valid absolute URL.","Check the environment variable or secret substituted into baseUrl for stray spaces/quotes.","Add a startup validation that url.Parse succeeds on every http source's baseUrl before serving."],"exampleFix":"# before\nbaseUrl: \"http://api.example.com/%zz\"\n# after\nbaseUrl: \"https://api.example.com\"","handlingStrategy":"validation","validationCode":"// Validate baseUrl when defining the source\nif _, err := url.Parse(strings.TrimSpace(os.Getenv(\"API_BASE_URL\"))); err != nil {\n    return fmt.Errorf(\"invalid API_BASE_URL: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"urlString, err := getURL(baseURL, path, pathParams, queryParams, defaultQuery, paramsMap)\nif err != nil {\n    if strings.HasPrefix(err.Error(), \"error parsing base URL\") {\n        return nil, fmt.Errorf(\"source baseUrl %q is not a valid URL: %w\", baseURL, err)\n    }\n    return nil, err\n}","preventionTips":["Quote baseUrl values in YAML and trim env-var substitutions","Avoid characters needing percent-encoding (spaces, control chars) in baseUrl","Validate baseUrl parses at source initialization to fail at startup"],"tags":["go","http","url","config"],"backgroundTag":"invalid-url-format","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}