Tencent/WeKnora · error

repository: last active owner

Error message

repository: last active owner

What it means

Sentinel ErrLastOwner returned by atomic demote/remove member helpers after row-locking active owners (FOR UPDATE): if the locked owner set would drop to zero — i.e. the target is the last active Owner — the operation aborts to keep the tenant with at least one owner.

Source

Thrown at internal/application/repository/tenant_member.go:19

package repository

import (
	"context"
	"errors"
	"strings"
	"time"

	"github.com/Tencent/WeKnora/internal/types"
	"github.com/Tencent/WeKnora/internal/types/interfaces"
	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

// ErrLastOwner is returned by the atomic demote / remove repo helpers
// when the operation would leave the tenant without an active Owner.
// The service layer maps this to its own ErrLastOwner sentinel (same
// semantic; just kept separate so the repo doesn't import service).
var ErrLastOwner = errors.New("repository: last active owner")

// forUpdateClause returns the gorm SELECT ... FOR UPDATE clause. Kept
// in one place so we can swap it out for `clause.Locking{Strength: "UPDATE"}`
// on databases that don't support row-level locking (none in our matrix,
// but keeps the seam if SQLite-lite ever needs a no-op).
func forUpdateClause() clause.Expression {
	return clause.Locking{Strength: "UPDATE"}
}

// tenantMemberRepository implements interfaces.TenantMemberRepository.
type tenantMemberRepository struct {
	db *gorm.DB
}

// NewTenantMemberRepository creates a new tenant member repository.
func NewTenantMemberRepository(db *gorm.DB) interfaces.TenantMemberRepository {
	return &tenantMemberRepository{db: db}
}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Promote another member to Owner before demoting/removing the current last owner
  2. Reject the operation with 400/409 in the service layer and explain the last-owner constraint
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at internal/application/repository/tenant_member.go:19 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/3aec5ef125ba0e60. Report an issue: GitHub.