juicedata/juicefs · error
not inserted or updated
Error message
not inserted or updated
What it means
sqlStore.Put reports "not inserted or updated" when both the INSERT and the fallback UPDATE affected zero rows (n == 0) without returning a driver error. The blob was not persisted, so the write is treated as failed.
Source
Thrown at pkg/object/sql.go:104
}
var n int64
now := time.Now()
b := blob{Key: []byte(key), Data: d, Size: int64(len(d)), Modified: now}
if name := s.db.DriverName(); name == "postgres" || name == "pgx" {
var r sql.Result
r, err = s.db.Exec("INSERT INTO jfs_blob(key, size,modified, data) VALUES(?, ?, ?,? ) "+
"ON CONFLICT (key) DO UPDATE SET size=?,data=?", []byte(key), b.Size, now, d, b.Size, d)
if err == nil {
n, err = r.RowsAffected()
}
} else {
n, err = s.db.Insert(&b)
if err != nil || n == 0 {
n, err = s.db.Update(&b, &blob{Key: []byte(key)})
}
}
if err == nil && n == 0 {
err = errors.New("not inserted or updated")
}
return err
}
func (s *sqlStore) Head(ctx context.Context, key string) (Object, error) {
var b = blob{Key: []byte(key)}
ok, err := s.db.Cols("key", "modified", "size").Get(&b)
if err != nil {
return nil, err
}
if !ok {
return nil, os.ErrNotExist
}
return &obj{
key,
b.Size,
b.Modified,
strings.HasSuffix(key, "/"),View on GitHub (pinned to c9a67b23e8)
Solutions
- Retry the Put; transient row-count quirks often succeed on retry
- Check the table schema (key column, primary key) matches what juicefs format created
- Upgrade the Go SQL driver / ensure it reports affected rows correctly (e.g. enable clientFoundRows for MySQL)
- Enable engine debug logging to capture the underlying insert/update errors
Example fix
// before
n, err = s.db.Insert(&b)
if err != nil || n == 0 {
n, err = s.db.Update(&b, &blob{Key: []byte(key)})
}
// after
n, err = s.db.Insert(&b)
if err != nil || n == 0 {
n, err = s.db.Update(&b, &blob{Key: []byte(key)})
if n == 0 && err == nil {
logger.Warnf("put %s: 0 rows affected, retrying", key)
}
} Defensive patterns
Strategy: retry
Validate before calling
// verify schema before writes
rows, _ := db.Query("SHOW TABLES LIKE 'jfs_blob'")
if !rows.Next() { /* volume not formatted against this DB */ } Try / catch
err := store.Put(ctx, key, r)
if err != nil && err.Error() == "not inserted or updated" {
time.Sleep(100*time.Millisecond)
err = store.Put(ctx, key, r) // retry once
} Prevention
- Keep the metadata schema aligned with the client version (re-run juicefs format/migrate as needed)
- Enable MySQL clientFoundRows if identical-value updates report 0 rows
- Watch engine logs for silent insert/update failures
- Retry transient write anomalies
When it happens
Trigger: Insert fails or inserts 0 rows, the subsequent Update by primary key matches no existing row (key absent and insert silently no-op), or a driver quirk reports 0 affected rows on successful upserts.
Common situations: MySQL with default CLIENT_FOUND_ROWS off where an UPDATE with identical data reports 0 affected rows; SQLite/Postgres schema mismatches; races where another client deleted the row between insert and update.
Related errors
- scan slice
- The entry of the root inode was not found
- ceph: can't put empty file
- GOOGLE_CLOUD_PROJECT environment variable must be set
- object key cannot be empty
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/d703d632a9e6c47c.
Report an issue: GitHub.