@@ -2312,15 +2312,21 @@ func (s *DHT) IterateBatchStore(ctx context.Context, values [][]byte, typ int, i
23122312 logtrace .Debug (ctx , "Iterate batch store: dispatching to nodes" , logtrace.Fields {"task_id" : id , "nodes" : len (knownNodes )})
23132313
23142314 // If there are no candidate nodes, there's nothing to fan out to. The caller
2315- // already persisted the batch locally (see StoreBatch), so treat this as a
2316- // no-op success rather than an error.
2315+ // already persisted the batch locally (see StoreBatch), but local-only
2316+ // persistence is not sufficient for network durability. Treat this as an
2317+ // error so callers do not finalize actions or delete source data under the
2318+ // assumption that replication occurred.
23172319 if len (knownNodes ) == 0 {
2318- logtrace .Info (ctx , "dht: batch store skipped (no candidate nodes)" , logtrace.Fields {
2319- logtrace .FieldModule : "dht" ,
2320- "task_id" : id ,
2321- "keys" : len (values ),
2320+ logtrace .Error (ctx , "dht: batch store skipped (no candidate nodes)" , logtrace.Fields {
2321+ logtrace .FieldModule : "dht" ,
2322+ "task_id" : id ,
2323+ "keys" : len (values ),
2324+ "len_nodes" : len (s .ht .nodes ()),
2325+ "banned_nodes" : len (ignoreList ),
2326+ "routing_allow_ready" : s .routingAllowReady .Load (),
2327+ "routing_allow_count" : s .routingAllowCount .Load (),
23222328 })
2323- return nil
2329+ return fmt . Errorf ( "no candidate nodes for batch store" )
23242330 }
23252331 storeResponses := s .batchStoreNetwork (ctx , values , knownNodes , storageMap , typ )
23262332 for response := range storeResponses {
0 commit comments