bytebase/bytebase · error
failed to update active VCS provider user
Error message
failed to update active VCS provider user
What it means
TouchVCSProviderUser first attempts a fast-path UPDATE ... RETURNING true to refresh an already-active VCS provider user. If Scan returns an error other than sql.ErrNoRows — the statement itself failed rather than simply matching no row — the store wraps it as "failed to update active VCS provider user". sql.ErrNoRows is deliberately treated as "user not currently active" and falls through to the transactional insert/reactivate path.
Source
Thrown at backend/store/vcs_provider_user.go:69
if payload == nil {
payload = &storepb.VCSProviderUserPayload{}
}
payloadBytes, err := protojson.Marshal(payload)
if err != nil {
return false, errors.Wrapf(err, "failed to marshal VCS provider user payload")
}
vcsType := user.VCSType.String()
var refreshed bool
if err := s.GetDB().QueryRowContext(ctx, `
UPDATE vcs_provider_user
SET last_seen_at = now(), payload = $4
WHERE workspace = $1 AND vcs_type = $2 AND user_id = $3
AND last_seen_at >= now() - make_interval(secs => $5)
RETURNING true
`, workspace, vcsType, user.UserID, payloadBytes, activeWindow.Seconds()).Scan(&refreshed); err != nil {
if err != sql.ErrNoRows {
return false, errors.Wrapf(err, "failed to update active VCS provider user")
}
} else {
return true, nil
}
tx, err := s.GetDB().BeginTx(ctx, nil)
if err != nil {
return false, errors.Wrapf(err, "failed to begin transaction")
}
defer tx.Rollback()
if err := AcquireAdvisoryXactLockWithStringKey(ctx, tx, AdvisoryLockKeyVCSProviderUser, workspace); err != nil {
return false, errors.Wrapf(err, "failed to acquire VCS provider user lock")
}
var active bool
if err := tx.QueryRowContext(ctx, `
SELECT last_seen_at >= now() - make_interval(secs => $4)View on GitHub (pinned to 1870550677)
Solutions
- Check metadata DB health and retry; transient connection/context errors usually resolve on retry.
- Verify vcs_provider_user exists and matches LATEST.sql; run migrations if the table is missing.
- Increase context timeouts for the VCS touch path if deadline cancellations occur under load.
- Inspect the wrapped driver error (pg error code) to pinpoint server-side causes like lock contention or statement timeouts.
Example fix
// before
refreshed, err := store.TouchVCSProviderUser(ctx, ws, user, window, limit)
if err != nil {
return fmt.Errorf("touch failed: %w", err)
}
// after (retry transient failures before giving up)
var refreshed bool
backoff := 100 * time.Millisecond
for i := 0; i < 3; i++ {
r, err := store.TouchVCSProviderUser(ctx, ws, user, window, limit)
if err == nil {
refreshed = r
break
}
if !isTransientNetErr(err) || i == 2 {
return fmt.Errorf("touch failed: %w", err)
}
time.Sleep(backoff)
backoff *= 2
} Defensive patterns
Strategy: retry
Validate before calling
// preflight: ensure the table exists and inputs are non-empty before touching
var exists bool
_ = db.QueryRowContext(ctx, "SELECT to_regclass('vcs_provider_user') IS NOT NULL").Scan(&exists)
if !exists || workspace == "" || user.UserID == "" || user.VCSType == v1pb.VCSType_VCS_TYPE_UNSPECIFIED {
return errors.New("invalid touch inputs or missing table")
} Try / catch
refreshed, err := store.TouchVCSProviderUser(ctx, ws, user, window, limit)
if err != nil {
if isTransientNetErr(err) {
refreshed, err = store.TouchVCSProviderUser(retryCtx, ws, user, window, limit)
}
if err != nil {
return fmt.Errorf("touch vcs provider user: %w", err)
}
} Prevention
- Pass a context with an adequate deadline; cancellation during the fast-path UPDATE surfaces through this error.
- Ensure migrations run before any GitOps/VCS traffic reaches the instance.
- Distinguish sql.ErrNoRows (expected, handled internally) from real failures — only retry the latter.
- Monitor pool saturation; this UPDATE runs on every VCS-authenticated request, so contention under load is a common trigger.
When it happens
Trigger: Calling TouchVCSProviderUser during a metadata DB outage or connection-pool exhaustion; the request context is cancelled while the UPDATE executes; the vcs_provider_user table is missing (unmigrated schema); parameter type/constraint errors.
Common situations: License-limit check during a Postgres failover; timeouts under load when many VCS users hit the GitOps endpoint concurrently; app running against a schema missing vcs_provider_user; transient context deadline cancellation.
Related errors
- failed to mark stale plan check runs as failed
- failed to mark sample instance setup deleted
- failed to move saved query folder
- failed to update VCS provider user
- CodeInternal
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/e5188ace8b0f0c2c.
Report an issue: GitHub.