{"record":{"id":"142f23bd5ba35b42","repo":"gastownhall/beads","slug":"db-removeremote-s-w","errorCode":null,"errorMessage":"db: RemoveRemote %s: %w","messagePattern":"db: RemoveRemote (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/domain/db/remote.go","lineNumber":33,"sourceCode":"}\n\ntype remoteSQLRepositoryImpl struct {\n\trunner Runner\n\tvc     DoltVersionControlSQLRepository\n}\n\nvar _ domain.RemoteSQLRepository = (*remoteSQLRepositoryImpl)(nil)\n\nfunc (r *remoteSQLRepositoryImpl) AddRemote(ctx context.Context, name, url string) error {\n\tif err := r.vc.Remote(ctx, \"add\", name, url); err != nil {\n\t\treturn fmt.Errorf(\"db: AddRemote %s: %w\", name, err)\n\t}\n\treturn nil\n}\n\nfunc (r *remoteSQLRepositoryImpl) RemoveRemote(ctx context.Context, name string) error {\n\tif err := r.vc.Remote(ctx, \"remove\", name); err != nil {\n\t\treturn fmt.Errorf(\"db: RemoveRemote %s: %w\", name, err)\n\t}\n\treturn nil\n}\n\nfunc (r *remoteSQLRepositoryImpl) ListRemotes(ctx context.Context) ([]domain.Remote, error) {\n\trows, err := r.runner.QueryContext(ctx, \"SELECT name, url FROM dolt_remotes\")\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"db: ListRemotes: query: %w\", err)\n\t}\n\tdefer rows.Close()\n\n\tvar remotes []domain.Remote\n\tfor rows.Next() {\n\t\tvar rem domain.Remote\n\t\tif err := rows.Scan(&rem.Name, &rem.URL); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"db: ListRemotes: scan: %w\", err)\n\t\t}\n\t\tremotes = append(remotes, rem)","sourceCodeStart":15,"sourceCodeEnd":51,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/domain/db/remote.go#L15-L51","documentation":"This error is returned by RemoveRemote when the underlying version-control layer (r.vc.Remote with the 'remove' subcommand) fails to delete a named remote. It wraps the VC error with the remote name for context, meaning the remote still exists in dolt_remotes.","triggerScenarios":"Calling RemoveRemote(ctx, name) where the underlying `dolt remote remove` fails: remote name does not exist, name mismatch/case, or backend error while updating dolt_remotes.","commonSituations":"Trying to clean up a remote that was already deleted; misspelled remote name; concurrent modification of the remotes table; removing a remote during an active sync that holds a reference.","solutions":["Read the wrapped cause after the remote name to see the VC error","Confirm the remote exists with ListRemotes before removing; treat 'not found' as success for idempotent cleanup","Check the exact remote name spelling/case","Retry if the failure was a transient backend lock/conflict"],"exampleFix":"// before\nif err := remotes.RemoveRemote(ctx, name); err != nil { return err }\n// after\nif err := remotes.RemoveRemote(ctx, name); err != nil {\n    if strings.Contains(err.Error(), \"not found\") { return nil } // already removed\n    return err\n}","handlingStrategy":"try-catch","validationCode":"remotes, err := store.ListRemotes(ctx)\nif err != nil { return err }\nfound := false\nfor _, r := range remotes { if r.Name == name { found = true } }\nif !found { return nil } // nothing to remove; treat as idempotent success","typeGuard":"func isRemoteNotFound(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"not found\")\n}","tryCatchPattern":"if err := store.RemoveRemote(ctx, name); err != nil {\n    if strings.Contains(err.Error(), \"not found\") {\n        return nil // already removed\n    }\n    return err\n}","preventionTips":["List remotes first and only remove names that exist","Treat 'not found' removals as success in cleanup scripts","Match remote names exactly (case-sensitive)"],"tags":["database","git-remote","dolt","sync"],"backgroundTag":"remote-remove-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}