{"record":{"id":"930ef3e0642125cd","repo":"iflytek/astron-agent","slug":"check-tenant-bootstrap-managed-credential-failed-w","errorCode":null,"errorMessage":"check tenant bootstrap managed credential failed: %w","messagePattern":"check tenant bootstrap managed credential failed: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tenant/tools/database/bootstrap_credentials.go","lineNumber":201,"sourceCode":"\terr = transaction.QueryRowContext(\n\t\tctx,\n\t\t`SELECT api_secret, is_delete\n\tFROM tb_auth\n\tWHERE app_id = ? AND api_key = ? AND COALESCE(extend, '') <> ?\n\tLIMIT 1 FOR UPDATE`,\n\t\tcredentials.TenantID,\n\t\tcredentials.APIKey,\n\t\ttenantBootstrapManagedMarker,\n\t).Scan(&unmanagedSecret, &unmanagedIsDelete)\n\tif err == nil {\n\t\tif !unmanagedSecret.Valid || !unmanagedIsDelete.Valid || unmanagedIsDelete.Bool ||\n\t\t\tsubtle.ConstantTimeCompare([]byte(unmanagedSecret.String), []byte(credentials.Secret)) != 1 {\n\t\t\treturn false, errors.New(\"tenant bootstrap API key conflicts with an unmanaged credential\")\n\t\t}\n\t\treturn true, nil\n\t}\n\tif err != nil && !errors.Is(err, sql.ErrNoRows) {\n\t\treturn false, fmt.Errorf(\"check tenant bootstrap managed credential failed: %w\", err)\n\t}\n\treturn false, nil\n}\n\nfunc adoptTenantBootstrapCredential(\n\tctx context.Context,\n\ttransaction bootstrapTransaction,\n\tcredentials config.TenantBootstrapCredentials,\n\tnow string,\n) error {\n\t// A strong pair explicitly configured by the deployment may already have\n\t// been created through Tenant's public API on an older release. Because it\n\t// belongs to the reserved app and exactly matches the current deployment\n\t// Secret, adopt it into managed ownership so a later rotation can retire it.\n\tif _, err := transaction.ExecContext(\n\t\tctx,\n\t\t`UPDATE tb_auth\nSET extend = ?, update_time = ?","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/tenant/tools/database/bootstrap_credentials.go#L183-L219","documentation":"findTenantBootstrapCredential wraps a database error that occurred while querying tb_auth for a managed (tenant-bootstrap-marked) credential row during tenant bootstrap reconciliation. The %w wrapper means an underlying MySQL/driver error was returned by QueryRowContext/Scan and it is not sql.ErrNoRows. It signals infrastructure failure of the credential-collision check, not a credential conflict.","triggerScenarios":"The second QueryRowContext inside findTenantBootstrapCredential (SELECT api_secret, is_delete FROM tb_auth WHERE app_id=? AND api_key=? AND COALESCE(extend,'')<>? ... FOR UPDATE) fails with any error other than sql.ErrNoRows, e.g. connection drop, lock wait timeout, table missing, or permissions error, while reconcileTenantBootstrapTransaction runs inside its DB transaction.","commonSituations":"MySQL is restarting or unreachable mid-transaction; the FOR UPDATE row lock times out under contention from concurrent bootstrap reconcilers; migrations were not applied so tb_auth or the extend column does not exist; the DB user lacks SELECT privilege on tb_auth.","solutions":["Check tenant service logs for the wrapped underlying driver error (%v of the cause) to identify the exact MySQL failure.","Verify MySQL connectivity, credentials, and that the tenant service can reach the DB host/port.","Confirm schema migrations for tb_auth (including extend and is_delete columns) have been applied.","If lock-wait timeouts appear, reduce concurrency of bootstrap reconciliation or raise innodb_lock_wait_timeout.","Retry the reconciliation once connectivity is restored; the operation is transactional and safe to re-run."],"exampleFix":"// before: no health check before reconcile\nreconcileTenantBootstrapTransaction(ctx, db, cfg)\n\n// after: verify DB reachable first\nif err := db.PingContext(ctx); err != nil {\n    return fmt.Errorf(\"database unavailable, skipping reconcile: %w\", err)\n}\nreturn reconcileTenantBootstrapTransaction(ctx, db, cfg)","handlingStrategy":"retry","validationCode":"if err := db.PingContext(ctx); err != nil { return fmt.Errorf(\"db not reachable before bootstrap reconcile: %w\", err) }","typeGuard":null,"tryCatchPattern":"err := reconcileTenantBootstrapTransaction(ctx, tx, cfg)\nvar retryable *mysql.MySQLError\nif errors.As(err, &retryable) && isTransientCode(retryable.Number) {\n    // retry with backoff\n}","preventionTips":["Run schema migrations before starting tenant bootstrap.","Grant the service account SELECT/UPDATE on tb_auth.","Monitor MySQL connectivity and lock-wait metrics.","Serialize bootstrap reconciliation runs with a lock."],"tags":["database","mysql","tenant-bootstrap","go"],"backgroundTag":"database-query-failed","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}