weaviate/weaviate · error
bucket '%s' must be in %s mode to be renamed
Error message
bucket '%s' must be in %s mode to be renamed
What it means
RenameBucket only permits renaming buckets that are in read-only mode (currBucket.isReadOnly() == false -> error). This prevents renaming a bucket that may still accept writes, which would break the invariant that writes land in the registered bucket name. The bucket must be flipped to storagestate.StatusReadOnly first.
Source
Thrown at adapters/repos/db/lsmkv/store.go:677
if s.closed {
return fmt.Errorf("%w: renaming bucket %q for %q in store %q", ErrAlreadyClosed, bucketName, newBucketName, s.dir)
}
s.bucketAccessLock.Lock()
defer s.bucketAccessLock.Unlock()
currBucket := s.bucketsByName[bucketName]
if currBucket == nil {
return fmt.Errorf("bucket '%s' not found", bucketName)
}
newBucket := s.bucketsByName[newBucketName]
if newBucket != nil {
return fmt.Errorf("bucket '%s' already exists", newBucketName)
}
if !currBucket.isReadOnly() {
return fmt.Errorf("bucket '%s' must be in %s mode to be renamed", bucketName, storagestate.StatusReadOnly)
}
currBucketDir := currBucket.dir
newBucketDir := s.bucketDir(newBucketName)
currBucket.flushLock.Lock()
defer currBucket.flushLock.Unlock()
if currBucket.flushing != nil {
return fmt.Errorf("bucket '%s' can not be renamed before flushing", bucketName)
}
currBucket.dir = newBucketDir
mt, err := currBucket.createNewActiveMemtable()
if err != nil {
return fmt.Errorf("switch active memtable: %w", err)
}View on GitHub (pinned to 75aa4b6d11)
Solutions
- Put the bucket into read-only mode before renaming (the shard/schema layer sets this, e.g. via shard.SetReadOnly / stop writes)
- Quiesce all writes to the bucket, then confirm its status is read-only, then rename
- If the bucket should never be writable, verify how it was created — a writable bucket requires the full read-only transition
Example fix
// before
err := store.RenameBucket(ctx, oldName, newName)
// after
bucket := store.Bucket(oldName)
if !bucket.IsReadOnly() {
if err := bucket.SetReadOnly(); err != nil { return err }
}
err := store.RenameBucket(ctx, oldName, newName) Defensive patterns
Strategy: validation
Validate before calling
b := store.Bucket(bucketName)
if b != nil && !b.IsReadOnly() {
return fmt.Errorf("bucket %q must be set read-only before rename", bucketName)
} Type guard
func bucketIsReadOnly(b *lsmkv.Bucket) bool { return b != nil && b.IsReadOnly() } Try / catch
if err := store.RenameBucket(ctx, a, b); err != nil {
if strings.Contains(err.Error(), "must be in read-only mode") {
return fmt.Errorf("put bucket in read-only (quiesce writes) before rename: %w", err)
}
return err
} Prevention
- Always transition the shard/bucket to read-only (stop writes + flush) before renaming
- Never rename during active ingest; quiesce writes at the schema/shard layer first
- Assert read-only status in migration code before invoking RenameBucket
When it happens
Trigger: Calling Store.RenameBucket on a bucket that is still writable — i.e. the caller did not put the bucket (or its shard) into read-only state before renaming.
Common situations: Migration code forgetting the read-only step; renaming a tenant shard bucket while writes are still flowing; calling rename during active ingest instead of after quiescing writes.
Related errors
- store is read-only
- flush memtable: %w
- bucket '%s' already exists
- failed renaming bucket dir '%s' to '%s'
- recoverCompressedVector: persisting recovered vector
AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04).
Data as JSON: /api/errors/be32d943d672dc46.
Report an issue: GitHub.