{"record":{"id":"edd0fa11545eaec9","repo":"multica-ai/multica","slug":"create-daemon-checkout-request-w","errorCode":null,"errorMessage":"create daemon checkout request: %w","messagePattern":"create daemon checkout request: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/multica/cmd_repo.go","lineNumber":381,"sourceCode":"\n\tdata, err := json.Marshal(reqBody)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"encode request: %w\", err)\n\t}\n\n\tparentCtx := cmd.Context()\n\tif parentCtx == nil {\n\t\tparentCtx = context.Background()\n\t}\n\tctx, cancel := context.WithTimeout(parentCtx, 5*time.Minute)\n\tdefer cancel()\n\tclient := &http.Client{}\n\tcheckoutURL := fmt.Sprintf(\"http://127.0.0.1:%s/repo/checkout\", daemonPort)\n\tvar body []byte\n\tfor {\n\t\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, checkoutURL, bytes.NewReader(data))\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"create daemon checkout request: %w\", err)\n\t\t}\n\t\treq.Header.Set(\"Content-Type\", \"application/json\")\n\t\tresp, err := client.Do(req)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"connect to daemon: %w\", err)\n\t\t}\n\t\tbody, err = io.ReadAll(resp.Body)\n\t\tcloseErr := resp.Body.Close()\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"read daemon checkout response: %w\", err)\n\t\t}\n\t\tif closeErr != nil {\n\t\t\treturn fmt.Errorf(\"close daemon checkout response: %w\", closeErr)\n\t\t}\n\t\tif resp.StatusCode == http.StatusServiceUnavailable && resp.Header.Get(\"X-Multica-Retryable\") == \"repo-busy\" {\n\t\t\tdelay := repoCheckoutRetryDelay(resp.Header.Get(\"Retry-After\"), time.Now())\n\t\t\ttimer := time.NewTimer(delay)\n\t\t\tselect {","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/multica/cmd_repo.go#L363-L399","documentation":"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).","triggerScenarios":"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.","commonSituations":"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\".","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."],"exampleFix":"# before\nexport MULTICA_DAEMON_PORT=\"8080 \"   # trailing space -> invalid URL\n\n# after\nexport MULTICA_DAEMON_PORT=8080\nmultica repo checkout https://github.com/acme/api","handlingStrategy":"validation","validationCode":"port := os.Getenv(\"MULTICA_DAEMON_PORT\")\nif n, err := strconv.Atoi(strings.TrimSpace(port)); err != nil || n < 1 || n > 65535 {\n\treturn fmt.Errorf(\"MULTICA_DAEMON_PORT=%q is not a valid port\", port)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["go","http","url-parsing","environment-variable","validation"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}