juicedata/juicefs · error
%d records not inserted: %+v
Error message
%d records not inserted: %+v
What it means
Thrown by the mustInsert helper when xorm's s.Insert reports success but the affected-row count is fewer than the number of beans in the batch (up to 200 per batch). This is an internal invariant: in normal SQL semantics a successful multi-row INSERT either affects all rows or errors, so a short insert signals rows silently skipped (e.g. driver quirks or ON-CONFLICT behaviors).
Source
Thrown at pkg/meta/sql.go:1030
m.genLog(Background(), s, time.Now().UnixNano(), "SET(%s,%d)", logEncode2(name), value)
}
return err
}
})
return changed, err
}
func mustInsert(s *xorm.Session, beans ...interface{}) error {
for start, end, size := 0, 0, len(beans); end < size; start = end {
end = start + 200
if end > size {
end = size
}
if n, err := s.Insert(beans[start:end]...); err != nil {
return err
} else if d := end - start - int(n); d > 0 {
return fmt.Errorf("%d records not inserted: %+v", d, beans[start:end])
}
}
return nil
}
func (m *dbMeta) batchUpdateChunkRefs(s *xorm.Session, chunkRefDeltas map[uint64]int) error {
if len(chunkRefDeltas) == 0 {
return nil
}
chunkIds := make([]uint64, 0, len(chunkRefDeltas))
for id, delta := range chunkRefDeltas {
if delta != 0 {
chunkIds = append(chunkIds, id)
}
}
if len(chunkIds) == 0 {
return nil
}View on GitHub (pinned to c9a67b23e8)
Solutions
- Inspect the listed beans (%+v) and check for duplicate primary keys or NULL key fields in the batch.
- Retry the operation; if it persists, test with a stock database driver version.
- File a bug with the driver name/version if a supported driver reliably short-inserts.
Example fix
// before: n < len(beans) with no error, mustInsert aborts the txn
// after: deduplicate beans before batch insert
seen := make(map[uint64]bool)
uniq := beans[:0]
for _, b := range beans { if !seen[key(b)] { seen[key(b)] = true; uniq = append(uniq, b) } }
err := mustInsert(s, uniq...) Defensive patterns
Strategy: validation
Validate before calling
// ensure batch inserts have unique, fully-populated primary keys
keys := make(map[interface{}]bool)
for _, b := range beans {
k := primaryKey(b)
if k == nil || keys[k] { return fmt.Errorf("bad batch: dup/nil key %v", k) }
keys[k] = true
} Try / catch
if err != nil && strings.Contains(err.Error(), "records not inserted") {
logger.Errorf("short insert detected, aborting txn; driver=%s beans=%v", driverName, err)
return err // txn rolls back; retry with deduplicated batch
} Prevention
- Use stock, supported database drivers; avoid patched drivers that misreport RowsAffected.
- Deduplicate bean batches on primary key before mustInsert.
- Keep xorm and driver versions aligned with upstream JuiceFS go.mod.
When it happens
Trigger: Any call site using mustInsert (session creation, chunk insertion, trash edge insertion, counter insert) where the driver returns a rowcount < len(beans) without an error — practically a driver/ORM anomaly or a batch containing duplicate primary keys with certain dialect configurations.
Common situations: Custom/patched SQL drivers that misreport affected rows; bulk inserts (e.g. during `juicefs fsck` re-linking or big trash scans) where a driver bug drops rows; extremely unusual on stock MySQL/PostgreSQL/SQLite drivers.
Related errors
- unable to use data source %s: %s
- format is not inserted
- insert new session %d: %s
- scan trash slices: %s
- produce meta records: %s
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/ed62d4a9ff80082f.
Report an issue: GitHub.