{"record":{"id":"954fe0b6e6b6d9da","repo":"gastownhall/beads","slug":"add-remote-s-w-954fe0","errorCode":null,"errorMessage":"add remote %s: %w","messagePattern":"add remote (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/issueops/federation.go","lineNumber":143,"sourceCode":"\t}\n\treturn peers, rows.Err()\n}\n\n// RemoveFederationPeerInTx deletes a federation peer by name.\nfunc RemoveFederationPeerInTx(ctx context.Context, tx *sql.Tx, name string) error {\n\t_, err := tx.ExecContext(ctx, \"DELETE FROM federation_peers WHERE name = ?\", name)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"remove federation peer: %w\", err)\n\t}\n\treturn nil\n}\n\n// AddRemoteIfNotExists adds a Dolt remote, ignoring \"already exists\" errors.\n// This is a helper used when adding federation peers that also need a Dolt remote.\nfunc AddRemoteIfNotExists(ctx context.Context, tx *sql.Tx, name, url string) error {\n\t_, err := tx.ExecContext(ctx, \"CALL DOLT_REMOTE('add', ?, ?)\", name, url)\n\tif err != nil && !strings.Contains(err.Error(), \"already exists\") {\n\t\treturn fmt.Errorf(\"add remote %s: %w\", name, err)\n\t}\n\treturn nil\n}\n","sourceCodeStart":125,"sourceCodeEnd":147,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/issueops/federation.go#L125-L147","documentation":"AddRemoteIfNotExists runs CALL DOLT_REMOTE('add', name, url) and wraps any failure other than \"already exists\" as \"add remote <name>\". It deliberately tolerates re-adding an existing remote, so this error means the stored procedure failed for another reason: invalid URL, bad remote name, or a Dolt engine error.","triggerScenarios":"Calling AddRemoteIfNotExists with an unreachable/malformed remote URL, an invalid remote name, or when the Dolt stored procedure rejects the call for reasons other than the remote already existing.","commonSituations":"Typo in the remote URL (missing scheme, wrong host); remote name with invalid characters; running against a non-Dolt backend that lacks the DOLT_REMOTE procedure; network/auth failure reaching the remote on validation.","solutions":["Read the wrapped error — if it contains \"already exists\" this is not a failure; otherwise inspect the DOLT_REMOTE message","Verify the URL is well-formed and reachable (https://host/org/repo)","Check the remote name for invalid characters and validate it before the call","Confirm the backend is Dolt and supports the DOLT_REMOTE stored procedure"],"exampleFix":"// before\nurl := cfg.Remote // \"host/org/repo\" (missing scheme)\nerr := issueops.AddRemoteIfNotExists(ctx, tx, \"origin\", url)\n// after\nurl := cfg.Remote\nif !strings.HasPrefix(url, \"https://\") && !strings.HasPrefix(url, \"http://\") {\n    url = \"https://\" + url\n}\nerr := issueops.AddRemoteIfNotExists(ctx, tx, \"origin\", url)","handlingStrategy":"validation","validationCode":"func validRemote(name, url string) error {\n    if name == \"\" || strings.ContainsAny(name, \" \\t/\") {\n        return fmt.Errorf(\"invalid remote name %q\", name)\n    }\n    u, err := neturl.Parse(url)\n    if err != nil || u.Scheme == \"\" || u.Host == \"\" {\n        return fmt.Errorf(\"invalid remote url %q\", url)\n    }\n    return nil\n}\n// call validRemote(name, url) before AddRemoteIfNotExists","typeGuard":null,"tryCatchPattern":"err := issueops.AddRemoteIfNotExists(ctx, tx, name, url)\nif err != nil {\n    if strings.Contains(err.Error(), \"already exists\") {\n        return nil // tolerated by design; should not surface\n    }\n    return fmt.Errorf(\"add remote %s: %w\", name, err)\n}","preventionTips":["Validate URL scheme/host and remote-name characters before calling","Remember \"already exists\" is intentionally swallowed — treat other messages as real failures","Confirm the backend is Dolt and supports DOLT_REMOTE before using this helper"],"tags":["dolt","federation","remote","go"],"backgroundTag":"dolt-remote-add-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}