multica-ai/multica · error
create daemon checkout request: %w
Error message
create daemon checkout request: %w
What it means
runRepoCheckout wraps the error from http.NewRequestWithContext for POST http://127.0.0.1:{MULTICA_DAEMON_PORT}/repo/checkout. NewRequestWithContext fails only for a malformed method or an unparseable URL. Since the method is constant and the host is fixed to 127.0.0.1, this fires only when MULTICA_DAEMON_PORT holds characters that break URL parsing (letters, whitespace, brackets).
Source
Thrown at server/cmd/multica/cmd_repo.go:381
data, err := json.Marshal(reqBody)
if err != nil {
return fmt.Errorf("encode request: %w", err)
}
parentCtx := cmd.Context()
if parentCtx == nil {
parentCtx = context.Background()
}
ctx, cancel := context.WithTimeout(parentCtx, 5*time.Minute)
defer cancel()
client := &http.Client{}
checkoutURL := fmt.Sprintf("http://127.0.0.1:%s/repo/checkout", daemonPort)
var body []byte
for {
req, err := http.NewRequestWithContext(ctx, http.MethodPost, checkoutURL, bytes.NewReader(data))
if err != nil {
return fmt.Errorf("create daemon checkout request: %w", err)
}
req.Header.Set("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("connect to daemon: %w", err)
}
body, err = io.ReadAll(resp.Body)
closeErr := resp.Body.Close()
if err != nil {
return fmt.Errorf("read daemon checkout response: %w", err)
}
if closeErr != nil {
return fmt.Errorf("close daemon checkout response: %w", closeErr)
}
if resp.StatusCode == http.StatusServiceUnavailable && resp.Header.Get("X-Multica-Retryable") == "repo-busy" {
delay := repoCheckoutRetryDelay(resp.Header.Get("Retry-After"), time.Now())
timer := time.NewTimer(delay)
select {View on GitHub (pinned to 2c0912b6ec)
Solutions
- Print the variable and strip junk: echo "[$MULTICA_DAEMON_PORT]"; re-export a clean numeric value.
- Validate in shell before running: case "$MULTICA_DAEMON_PORT" in ''|*[!0-9]*) echo "bad port"; exit 1;; esac.
- If the value comes from an env file, convert line endings (dos2unix) or quote it correctly.
Example fix
# before export MULTICA_DAEMON_PORT="8080 " # trailing space -> invalid URL # after export MULTICA_DAEMON_PORT=8080 multica repo checkout https://github.com/acme/api
Defensive patterns
Strategy: validation
Validate before calling
port := os.Getenv("MULTICA_DAEMON_PORT")
if n, err := strconv.Atoi(strings.TrimSpace(port)); err != nil || n < 1 || n > 65535 {
return fmt.Errorf("MULTICA_DAEMON_PORT=%q is not a valid port", port)
} Prevention
- Validate the env var is pure digits before running checkout commands.
- Watch for CRLF contamination in .env files when exporting daemon vars.
- Prefer injecting the port programmatically (daemon env) over hand-editing it.
When it happens
Trigger: MULTICA_DAEMON_PORT set to a non-numeric value, e.g. "8080 " (trailing whitespace), "http" or "8_080", making "http://127.0.0.1:8_080/repo/checkout" invalid.
Common situations: Manually exporting MULTICA_DAEMON_PORT with a typo when testing outside the daemon; env files with CRLF line endings appending \r to the value; templates injecting a unit like "8080tcp".
Related errors
- empty body
- body must be a JSON object or array
- copy agent: %w
- create skill: %w
- Invalid desktop runtime config: ${field} must use http or ht
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/edd0fa11545eaec9.
Report an issue: GitHub.