siyuan-note/siyuan · error

OIDC configuration changed during validation

Error message

OIDC configuration changed during validation

What it means

activateOIDCValidation applies the validated candidate config via Conf.CompareAndSetOIDC(transaction.ConfigVersion, transaction.Config). CompareAndSetOIDC performs an optimistic compare-and-swap against the live config version; if the version no longer matches — meaning the OIDC configuration was edited while validation was in progress — the swap fails, the transaction is deleted, and this error is returned.

Solutions

  1. Re-run the full validation flow (OIDCValidateStart → poll → activate) against the current configuration
  2. Serialize OIDC configuration edits so validation and save cannot interleave (single-admin workflow or lock the settings panel)
  3. Surface the error in the UI as 'settings changed, please re-validate' and auto-restart validation
  4. Compare config versions client-side before activating and warn the user early

Example fix

// before
swapped, err := model.OIDCValidateActivate(pollToken, binding) // config edited mid-flow -> "changed during validation"
// after
// restart validation against the new config
start, _ := model.OIDCValidateStart(redirectURL)
// poll then activate with the new transaction
Defensive patterns

Strategy: try-catch

Validate before calling

// compare config version before activating
if txn.ConfigVersion != model.OIDCConfigurationVersion() { warnConfigChanged(); restartValidation() }

Try / catch

ok, changed, err := model.OIDCValidateActivate(pollToken, binding)
if err != nil && strings.Contains(err.Error(), "changed during validation") {
    // settings were edited mid-flow: restart validation against current config
    return restartOIDCValidation()
}

Prevention

When it happens

Trigger: An admin saved OIDC settings (bumping the config version) between the start of validation and the OIDCValidateActivate call; concurrent configuration updates from another admin session or via the settings API during the validation window.

Common situations: Two admins editing auth settings simultaneously; an automated config sync rewrites conf while a user is completing validation; user edits another OIDC field in the panel, then submits the previously validated flow.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/28ec85e8deebdd9b. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/oidc.go:785

	oidcTransactions.Lock()
	defer oidcTransactions.Unlock()
	cleanupOIDCTransactionsLocked()
	state := oidcTransactions.byPoll[pollToken]
	transaction := oidcTransactions.byState[state]
	if transaction == nil || transaction.Flow != oidcFlowValidate || transaction.Binding == "" ||
		binding == "" || transaction.Binding != binding || !transaction.Completed || !transaction.Success {
		return false, errors.New("OIDC validation transaction was not found or has expired")
	}
	if transaction.Activated {
		return false, nil
	}
	if transaction.Config == nil {
		return false, errors.New("OIDC validation configuration is missing")
	}
	configurationChanged, swapped := Conf.CompareAndSetOIDC(transaction.ConfigVersion, transaction.Config)
	if !swapped {
		deleteOIDCTransactionLocked(state)
		return false, errors.New("OIDC configuration changed during validation")
	}
	transaction.Config = nil
	transaction.Activated = true
	return configurationChanged, nil
}

func cancelOIDCValidation(pollToken, binding string) bool {
	oidcTransactions.Lock()
	defer oidcTransactions.Unlock()
	cleanupOIDCTransactionsLocked()
	state := oidcTransactions.byPoll[pollToken]
	transaction := oidcTransactions.byState[state]
	if transaction == nil || transaction.Flow != oidcFlowValidate || transaction.Activated || transaction.Binding == "" ||
		binding == "" || transaction.Binding != binding {
		return false
	}
	deleteOIDCTransactionLocked(state)
	return true

View on GitHub (pinned to 9f775e8a12)