{"record":{"id":"2c17a69c7c682548","repo":"siyuan-note/siyuan","slug":"oidc-validation-transaction-was-not-found-or-has-e","errorCode":null,"errorMessage":"OIDC validation transaction was not found or has expired","messagePattern":"OIDC validation transaction was not found or has expired","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/oidc.go","lineNumber":830,"sourceCode":"\tstate := oidcTransactions.byPoll[pollToken]\n\ttransaction := oidcTransactions.byState[state]\n\tif transaction == nil || (transaction.Flow != oidcFlowDesktop && transaction.Flow != oidcFlowValidate) ||\n\t\tbinding == \"\" || binding != transaction.Binding {\n\t\treturn nil, false\n\t}\n\tcopy := *transaction\n\treturn &copy, true\n}\n\nfunc activateOIDCValidation(pollToken, binding string) (activated bool, err error) {\n\toidcTransactions.Lock()\n\tdefer oidcTransactions.Unlock()\n\tcleanupOIDCTransactionsLocked()\n\tstate := oidcTransactions.byPoll[pollToken]\n\ttransaction := oidcTransactions.byState[state]\n\tif transaction == nil || transaction.Flow != oidcFlowValidate || transaction.Binding == \"\" ||\n\t\tbinding == \"\" || transaction.Binding != binding || !transaction.Completed || !transaction.Success {\n\t\treturn false, errors.New(\"OIDC validation transaction was not found or has expired\")\n\t}\n\tif transaction.Activated {\n\t\treturn false, nil\n\t}\n\tif transaction.Config == nil {\n\t\treturn false, errors.New(\"OIDC validation configuration is missing\")\n\t}\n\tconfigurationChanged, swapped := Conf.CompareAndSetOIDC(transaction.ConfigVersion, transaction.Config)\n\tif !swapped {\n\t\tdeleteOIDCTransactionLocked(state)\n\t\treturn false, errors.New(\"OIDC configuration changed during validation\")\n\t}\n\ttransaction.Config = nil\n\ttransaction.Activated = true\n\treturn configurationChanged, nil\n}\n\nfunc cancelOIDCValidation(pollToken, binding string) bool {","sourceCodeStart":812,"sourceCodeEnd":848,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/oidc.go#L812-L848","documentation":"activateOIDCValidation could not resolve the poll token to a validate-flow transaction that is completed, successful, and has a matching binding. Activation only runs against a transaction that finished the IdP round-trip successfully.","triggerScenarios":"Calling /api/system/oidc/validateActivate with a stale or wrong poll token, before validation completed, after it failed, after its 30s completed window elapsed, after cancellation, or with the wrong binding.","commonSituations":"User clicks Activate twice or after a delay; poll token copy-paste error; activation attempted against a transaction whose binding changed.","solutions":["Re-run validation from /api/system/oidc/validate to get a fresh poll token.","Activate within the completed window (30 seconds after the IdP success).","Confirm the poll token and binding match the validation session that was started."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Only call validateActivate after a successful poll; require non-empty poll token and binding.\nif pollToken == \"\" || binding == \"\" {\n    return errors.New(\"poll token and binding are required\")\n}\nif tx, ok := pollOIDCTransaction(pollToken, binding); !ok || !tx.Completed || !tx.Success {\n    return errors.New(\"validation not ready; poll again\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Poll until Completed && Success before attempting activation.","Activate within the 30-second completed window.","Do not reuse poll tokens across validation runs."],"tags":["oidc","validation","activation","expiry"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}