plandex-ai/plandex · error
Error creating request for proxy
Error message
Error creating request for proxy
What it means
proxyRequest builds an outbound http.NewRequestWithContext to clone the incoming request and forward it to the instance IP hosting the plan. If that construction fails, the handler returns HTTP 500 "Error creating request for proxy". http.NewRequestWithContext errors on an invalid URL or an unparsable method — almost always a malformed proxy URL.
Source
Thrown at app/server/handlers/proxy_helper.go:66
proxyUrl := fmt.Sprintf("http://%s:%s/plans/%s/%s/%s", modelStream.InternalIp, os.Getenv("PORT"), planId, branch, method)
proxyUrl += "?proxy=true"
log.Printf("Proxy url: %s\n", proxyUrl)
proxyRequest(w, r, proxyUrl)
return
}
}
func proxyRequest(w http.ResponseWriter, originalRequest *http.Request, url string) {
client := &http.Client{
Timeout: time.Second * 10,
}
// Create a new request based on the original request
req, err := http.NewRequestWithContext(originalRequest.Context(), originalRequest.Method, url, originalRequest.Body)
if err != nil {
log.Printf("Error creating request for proxy: %v\n", err)
http.Error(w, "Error creating request for proxy", http.StatusInternalServerError)
return
}
// Copy the headers from the original request to the new request
for name, headers := range originalRequest.Header {
for _, h := range headers {
req.Header.Add(name, h)
}
}
// Copy the body from the original request to the new request if it's a POST or PUT
if originalRequest.Method == http.MethodPost || originalRequest.Method == http.MethodPut {
req.Body = originalRequest.Body
}
// Make the request
resp, err := client.Do(req)
if err != nil {View on GitHub (pinned to e2d772072e)
Solutions
- Read the server log for the exact NewRequestWithContext error — it names the malformed URL.
- Log/validate the composed proxyUrl before creating the request; url.Parse it to catch malformed pieces.
- Ensure InternalIp is a bare IP/host set during stream registration; reject empty values earlier.
- Use url.PathEscape for planId/branch/method path segments and validate PORT is set at startup.
- Verify with url.Parse(proxyUrl) in tests that all lifecycle paths produce valid URLs.
Example fix
// before
proxyUrl := fmt.Sprintf("http://%s:%s/plans/%s/%s/%s", modelStream.InternalIp, os.Getenv("PORT"), planId, branch, method)
req, err := http.NewRequestWithContext(originalRequest.Context(), originalRequest.Method, url, originalRequest.Body)
// after
if modelStream.InternalIp == "" {
http.Error(w, "Internal IP missing for plan stream", http.StatusBadGateway)
return
}
port := os.Getenv("PORT")
if port == "" { port = "8080" }
proxyUrl := fmt.Sprintf("http://%s:%s/plans/%s/%s/%s",
modelStream.InternalIp, port,
url.PathEscape(planId), url.PathEscape(branch), url.PathEscape(method))
if _, err := url.Parse(proxyUrl); err != nil {
http.Error(w, "Invalid proxy URL", http.StatusBadGateway)
return
}
req, err := http.NewRequestWithContext(originalRequest.Context(), originalRequest.Method, proxyUrl, originalRequest.Body) Defensive patterns
Strategy: validation
Validate before calling
// server-side: validate URL parts before building the request
if modelStream.InternalIp == "" || os.Getenv("PORT") == "" {
http.Error(w, "Proxy target not configured", http.StatusBadGateway)
return
}
if _, err := url.Parse(fmt.Sprintf("http://%s:%s", modelStream.InternalIp, os.Getenv("PORT"))); err != nil {
http.Error(w, "Invalid proxy target", http.StatusBadGateway)
return
} Try / catch
// caller of the proxied endpoint
try {
const res = await fetch(`/plans/${planId}/${branch}/connect`);
if (res.status === 500) console.error('Proxy misconfigured — check server logs for URL error');
} catch (e) { console.error(e); } Prevention
- Validate InternalIp and PORT at stream registration time, not at proxy time.
- Escape all path segments with url.PathEscape before interpolation.
- Fail fast on missing required env vars (PORT) at startup.
- Add unit tests asserting the composed proxyUrl parses for all lifecycle paths.
When it happens
Trigger: modelStream.InternalIp empty or malformed, producing a bad URL like "http://:8080/plans/..."; planId/branch/method containing characters that break URL formatting (spaces, slashes, control chars); os.Getenv("PORT") empty yielding an invalid host:port; context already canceled passed to NewRequestWithContext (rare).
Common situations: Internal IP not set on the stream row (registration bug); un-encoded path segments from user input interpolated into the URL; PORT env var unset in a new deployment; IPv6 or hostname with scheme accidentally stored in InternalIp.
Related errors
- Error getting active model stream
- Error forwarding request
- error getting current plan state params: %v
- error getting contexts: %v
- error creating request: %w
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/bea2231fb437c474.
Report an issue: GitHub.