Skip to content

fix(coderd): stop retrying git provider types that have no implementation - #29997

Open
bharadwaj-pendyala wants to merge 1 commit into
coder:mainfrom
bharadwaj-pendyala:fix/gitsync-park-unimplemented-providers
Open

bharadwaj-pendyala wants to merge 1 commit into
coder:mainfrom
bharadwaj-pendyala:fix/gitsync-park-unimplemented-providers

Conversation

@bharadwaj-pendyala

Copy link
Copy Markdown

Closes #28141.

Five configured git provider types (bitbucket-cloud, bitbucket-server, azure-devops, azure-devops-entra, gitea) get (nil, nil) back from gitprovider.New. Every affected chat_diff_statuses row is re-queued every DiffStatusTTL and never succeeds. The log blames origin matching, sending operators toward a config mistake that isn't there.

resolveGitProvider returned a bare gitprovider.Provider, so "no config matched this origin" and "a config matched but Coder doesn't implement its git type" both reached Refresher.Refresh as nil. The first is operator-fixable; the second needs different retry behavior.

ProviderResolver now returns (gitprovider.Provider, error). resolveExternalAuth reports gitsync.ErrProviderUnimplemented when every matching config names a git type with no implementation, mirroring the existing gitsync.ErrNoTokenAvailable result from the token resolver.

Worker.tick parks those rows for NotImplementedBackoff (24h) in the same branch as ErrNoTokenAvailable. No flag or column is added, so MarkStale still revives a row on the next reported git activity. Backoff writes per affected chat per day go from 720 to 1.

Construction errors take precedence over the unimplemented signal. A GitLab config with a bad APIBaseURL returns create gitlab client: failed to parse base URL; parking that deployment error for a day would hide it. This occurs when two configs match the same origin. The no-match path is unchanged, including no provider for origin %q.

BackoffChatDiffStatus filters on chat_id alone, so a MarkStale that lands during a tick can be overwritten by the backoff write. The race already exists for NoTokenBackoff and NoPRBackoff, but 24h increases its wall-clock cost. A compare-and-swap on updated_at would close it: UpsertChatDiffStatusReference bumps updated_at (chats.sql:1968), while the backoff query deliberately leaves it unchanged (chats.sql:2297). Fixing that requires changing shared SQL for a race this PR didn't introduce.

Editing external auth so the origin matches an implemented provider does not wake a parked row. The operator can wait up to 24h instead of two minutes, and restarting coderd doesn't clear it.

Sabotage checks:

--- FAIL: TestWorker_NotImplementedBackoff
    Error: Max difference between 2024-01-02 00:00:10 +0000 UTC and 2024-01-01 00:02:10 +0000 UTC allowed is 1s, but difference was 23h58m0s

This failure occurs after dropping the ErrProviderUnimplemented case from Worker.tick.

--- FAIL: TestResolveExternalAuthProviderErrors/construction_failure_wins_over_an_unimplemented_type
    Error: Error "git provider not implemented" does not contain "construct git provider \"gl\""

This failure occurs after dropping construction-error precedence.

Resolver results for https://bitbucket.org/acme/api with one matching external auth config per type:

type=bitbucket-cloud     unimplemented=true  err=git provider not implemented
type=bitbucket-server    unimplemented=true  err=git provider not implemented
type=azure-devops        unimplemented=true  err=git provider not implemented
type=azure-devops-entra  unimplemented=true  err=git provider not implemented
type=gitea               unimplemented=true  err=git provider not implemented
type=github              unimplemented=false err=<nil>
type=jfrog               unimplemented=false err=<nil>

jfrog is a non-git type, so it keeps the short retry instead of parking.

$ go test ./coderd/x/gitsync/ -count=1 -race
ok  github.com/coder/coder/v2/coderd/x/gitsync 3.183s

$ go test ./coderd/ -run 'TestResolveExternalAuth|TestIsZeroChatModelCall|TestChat' -count=1
ok  github.com/coder/coder/v2/coderd 132.381s

$ golangci-lint run ./coderd/x/gitsync/...
0 issues.

Local golangci-lint is 2.14.0; the repository pins v2.0.2. Under the newer version, the coderd package already has 131 findings on main, so CI is the real check there.

🤖 Built with AI assistance.

…tion

Five configured git provider types (bitbucket-cloud, bitbucket-server,
azure-devops, azure-devops-entra, gitea) get (nil, nil) from
gitprovider.New, so gitsync re-queued every affected chat_diff_statuses
row every DiffStatusTTL and the log blamed origin matching.

resolveExternalAuth now reports ErrProviderUnimplemented when every
matching config names a git type Coder does not implement, and
Worker.tick parks those rows for NotImplementedBackoff. A provider that
failed to build takes precedence, since an operator can fix that.

Closes coder#28141
@github-actions

Copy link
Copy Markdown
Contributor


Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@github-actions github-actions Bot added the community Pull Requests and issues created by the community. label Sep 26, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community Pull Requests and issues created by the community.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(coderd/x/gitsync): stop retrying unimplemented git provider types forever

1 participant