{"record":{"id":"cf7d9113909ba081","repo":"multica-ai/multica","slug":"checkout-failed-s","errorCode":null,"errorMessage":"checkout failed: %s","messagePattern":"checkout failed: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/cmd/multica/cmd_repo.go","lineNumber":408,"sourceCode":"\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 {\n\t\t\tcase <-ctx.Done():\n\t\t\t\ttimer.Stop()\n\t\t\t\treturn fmt.Errorf(\"connect to daemon: %w\", context.Cause(ctx))\n\t\t\tcase <-timer.C:\n\t\t\t\tcontinue\n\t\t\t}\n\t\t}\n\t\tif resp.StatusCode != http.StatusOK {\n\t\t\treturn fmt.Errorf(\"checkout failed: %s\", string(body))\n\t\t}\n\t\tbreak\n\t}\n\n\tvar result struct {\n\t\tPath       string `json:\"path\"`\n\t\tBranchName string `json:\"branch_name\"`\n\t}\n\tif err := json.Unmarshal(body, &result); err != nil {\n\t\treturn fmt.Errorf(\"parse response: %w\", err)\n\t}\n\n\tfmt.Fprintf(os.Stdout, \"%s\\n\", result.Path)\n\tfmt.Fprintf(os.Stderr, \"Checked out %s → %s (branch: %s)\\n\", repoURL, result.Path, result.BranchName)\n\n\treturn nil\n}\n","sourceCodeStart":390,"sourceCodeEnd":426,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/cmd/multica/cmd_repo.go#L390-L426","documentation":"The daemon answered the checkout POST with a non-200, non-retryable-busy status, so runRepoCheckout surfaces the raw response body: \"checkout failed: <body>\". The daemon owns the message — typical bodies include git clone failures, bad refs, disk-full, or invalid workspace/repo state. The CLI makes no attempt to parse it.","triggerScenarios":"Repository URL unreachable or requires auth (clone fails); requested ref does not exist; the checkout_mode passed via MULTICA_REPO_CHECKOUT_MODE is unsupported; daemon-side disk exhaustion; workspace_id missing or unknown to the daemon.","commonSituations":"Private repo without credentials in the daemon environment; typo'd branch in repoCheckoutRef; agent environment lost MULTICA_WORKSPACE_ID so workspace_id was sent empty; CI runners with full disks.","solutions":["Read the body text in the error — it is the daemon's verbatim message and names the exact cause (clone auth, ref, disk).","If it is an auth failure, ensure the daemon has credentials for the repo (SSH key/token in the daemon env, not your shell).","If the ref is wrong, verify it exists (git ls-remote <url> <ref>) and re-run with the correct --ref value.","If workspace_id is empty in the error context, re-run inside a proper daemon task so MULTICA_WORKSPACE_ID is set."],"exampleFix":"# before\nmultica repo checkout https://github.com/acme/api --ref main-typo\n# checkout failed: ref not found: main-typo\n\n# after\ngit ls-remote https://github.com/acme/api | grep main\nmultica repo checkout https://github.com/acme/api --ref main","handlingStrategy":"try-catch","validationCode":"# pre-flight the repo and ref before asking the daemon\ngit ls-remote \"$URL\" \"$REF\" >/dev/null || { echo 'bad URL or ref' >&2; exit 1; }","typeGuard":null,"tryCatchPattern":"if resp.StatusCode != http.StatusOK {\n\treturn fmt.Errorf(\"checkout failed (%d): %s\", resp.StatusCode, string(body)) // keep status for programmatic handling\n}","preventionTips":["Read the daemon's body text — it states the exact cause.","Ensure daemon-side credentials exist for private repos.","Validate refs and MULTICA_REPO_CHECKOUT_MODE values before launching tasks."],"tags":["go","cli","http","daemon","git","checkout"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}