flat.Delete leaves AlreadyIndexed() live-vector count stale
Author: leemeiiCreated Sep 7, 2026Updated Sep 10, 2026
Labelsbugcommunity
How to reproduce this bug?
Use the following minimal reproduction script. It temporarily creates a Go test file, runs the test, and removes the file afterward.
#!/usr/bin/env python3
import os
import subprocess
import sys
from pathlib import Path
root = Path(os.environ.get("WEAVIATE_ROOT", ".")).resolve()
test_file = root / "adapters/repos/db/vector/flat/audit_delete_count_test.go"
go_test = r'''
package flat
import (
"context"
"fmt"
"testing"
"github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/require"
"github.com/weaviate/weaviate/adapters/repos/db/lsmkv"
"github.com/weaviate/weaviate/adapters/repos/db/vector/hnsw/distancer"
flatent "github.com/weaviate/weaviate/entities/vectorindex/flat"
)
func TestFlatDeleteCount(t *testing.T) {
logger, _ := test.NewNullLogger()
root := t.TempDir()
store := testStore(t, root, logger)
defer store.Shutdown(context.Background())
cfg := flatent.UserConfig{}
cfg.SetDefaults()
idx, err := New(Config{
ID: "audit",
RootPath: root,
DistanceProvider: distancer.NewCosineDistanceProvider(),
MakeBucketOptions: lsmkv.MakeRegularBucketOptions,
}, cfg, store)
require.NoError(t, err)
defer idx.Shutdown(context.Background())
require.NoError(t, idx.Add(context.Background(), 7, []float32{1, 0}))
require.NoError(t, idx.Add(context.Background(), 8, []float32{0, 1}))
before := idx.AlreadyIndexed()
require.NoError(t, idx.Delete(7))
after := idx.AlreadyIndexed()
fmt.Printf(
"before=%d after=%d contains_deleted=%v remaining=%v\n",
before, after, idx.ContainsDoc(7), idx.ContainsDoc(8),
)
if before != 2 || after != 1 ||
idx.ContainsDoc(7) || !idx.ContainsDoc(8) {
t.Fatalf("unexpected live-vector state")
}
}
'''
if not (root / "go.mod").exists():
print("WEAVIATE_ROOT must point to a Weaviate checkout", file=sys.stderr)
sys.exit(2)
test_file.write_text(go_test)
try:
result = subprocess.run(
[
os.environ.get("GO", "go"),
"test",
"./adapters/repos/db/vector/flat",
"-run",
"^TestFlatDeleteCount$",
"-count=1",
"-v",
],
cwd=root,
text=True,
capture_output=True,
)
finally:
test_file.unlink(missing_ok=True)
print(result.stdout, end="")
print(result.stderr, end="", file=sys.stderr)
if (
result.returncode == 1
and "before=2 after=2 contains_deleted=false remaining=true" in result.stdout
):
print("BUG REPRODUCED")
sys.exit(0)
if result.returncode == 0 and "before=2 after=1" in result.stdout:
print("BUG NOT REPRODUCED")
sys.exit(1)
print("ENVIRONMENT OR ORACLE FAILURE", file=sys.stderr)
sys.exit(2)Run:
WEAVIATE_ROOT=/path/to/weaviate python3 repro.pyWhat is the expected behavior?
After:
Add(7)
Add(8)
Delete(7)only vector ID 8 remains. The expected output is:
before=2 after=1 contains_deleted=false remaining=trueTherefore:
AlreadyIndexed() == 1
ContainsDoc(7) == false
ContainsDoc(8) == trueWhat is the actual behavior?
The actual output is:
before=2 after=2 contains_deleted=false remaining=trueThe deletion correctly removes ID 7, but AlreadyIndexed() continues to report 2.
Supporting information
No response
Server Version
1.40.0
Weaviate Setup
Single Node
Nodes count
No response
Code of Conduct
- I have read and agree to the Weaviate's Contributor Guide and Code of Conduct
Source: weaviate/weaviate