siyuan-note/siyuan · error

OIDC validation configuration is missing

Error message

OIDC validation configuration is missing

What it means

During activation of a validated OIDC configuration, the transaction record must still carry the candidate config snapshot (transaction.Config). If Config is nil the candidate configuration cannot be applied, so activateOIDCValidation aborts. This indicates internal state corruption or a transaction whose config was already consumed.

Solutions

  1. Recreate the validation transaction via OIDCValidateStart so a fresh candidate config snapshot is attached
  2. Ensure finishOIDCExchange ran for the validate flow and attached transaction.Config before activation
  3. Audit concurrent activation paths — guard against a second activation operating on the same transaction
  4. Check the transaction's Flow is oidcFlowValidate; a login-flow transaction has no candidate Config

Example fix

// before
transaction := &oidcTransaction{Flow: oidcFlowValidate, Binding: b, Completed: true, Success: true}
// after
transaction := &oidcTransaction{Flow: oidcFlowValidate, Binding: b, Completed: true, Success: true, Config: candidateConf, ConfigVersion: ver}
Defensive patterns

Strategy: type-guard

Validate before calling

// ensure the validate transaction carries a candidate config before activating
if txn.Flow == oidcFlowValidate && txn.Config == nil { return ErrNoCandidateConfig }

Type guard

func hasCandidateConfig(txn *oidcTransaction) bool {
    return txn != nil && txn.Flow == oidcFlowValidate && txn.Config != nil
}

Try / catch

ok, err := model.OIDCValidateActivate(pollToken, binding)
if err != nil && strings.Contains(err.Error(), "configuration is missing") {
    return restartOIDCValidation() // rebuild transaction with attached config
}

Prevention

When it happens

Trigger: Calling OIDCValidateActivate on a transaction that went through finishOIDCExchange as a non-validate flow, a transaction whose Config was already set to nil after a previous successful activation (Activated handled earlier, but ordering/nil paths in tests), or a manually constructed/corrupted transaction in tests TestActivateOIDCValidationAppliesCandidateOnce/RejectsChangedConfiguration/CancelOIDCValidationPreventsActivation.

Common situations: Race where activation runs twice concurrently and the second call sees a mutated transaction; custom test harness builds a validate-flow transaction without attaching Config; memory corruption after partial failure during exchange.

Related errors


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

Appendix: source

Thrown at kernel/model/oidc.go:780

	copy := *transaction
	return &copy, true
}

func activateOIDCValidation(pollToken, binding string) (activated bool, err error) {
	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 == "" ||

View on GitHub (pinned to 9f775e8a12)