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

  1. Retry the Put; transient row-count quirks often succeed on retry
  2. Check the table schema (key column, primary key) matches what juicefs format created
  3. Upgrade the Go SQL driver / ensure it reports affected rows correctly (e.g. enable clientFoundRows for MySQL)
  4. 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

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


AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/d703d632a9e6c47c. Report an issue: GitHub.