weaviate/weaviate · error

merge object data

Error message

merge object data

What it means

This wrapper is returned from Shard.mergeObjectInStorage when s.mergeObjectData fails while applying a PATCH (partial merge) to an existing object stored in the shard's LSM objects bucket. mergeObjectData deep-copies the previous object and overlays the merge document's primitive properties, references, PropertiesToDelete, and vectors (mergeProps). Notably, if the previous object is nil (should not happen here, since nil was rejected just above), mergeObjectData logs 'resurrecting a zombie object' and synthesizes an empty base object, so most failures come from the overlay logic itself.

Source

Thrown at adapters/repos/db/shard_write_merge.go:177

		s.asyncReplicationRWMux.RLock()
		defer s.asyncReplicationRWMux.RUnlock()

		lock.Lock()
		defer lock.Unlock()

		var err error
		prevObj, err = fetchObject(bucket, idBytes)
		if err != nil {
			return errors.Wrap(err, "get bucket")
		}

		if prevObj == nil {
			return errObjectNotFound
		}

		obj, _, err = s.mergeObjectData(prevObj, merge)
		if err != nil {
			return errors.Wrap(err, "merge object data")
		}

		// A property-only merge carries the previous version's vectors forward;
		// a dropped one must not be re-persisted into a new segment.
		stripDroppedVectors(class, obj)

		status, err = s.determineInsertStatus(prevObj, obj)
		if err != nil {
			return errors.Wrap(err, "check insert/update status")
		}

		obj.DocID = status.docID
		if status.skipUpsert {
			return nil
		}

		objBytes, err := obj.MarshalBinaryDisk(s.index.Config.SkipWriteClassNameOnDisk)
		if err != nil {

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Check the wrapped inner error in the log; it names the exact failing sub-step of the overlay
  2. Verify the object exists and is readable via GET before retrying the PATCH
  3. If the object looks corrupt, re-import (re-create) the affected object rather than patching it
  4. Upgrade to a version where mergeProps handles the stored property type defensively

Example fix

// server-side wrapper is informational; ensure callers check the full error chain
if err := client.Schema().MergeObject(ctx, mergeDoc); err != nil {
    log.Printf("merge failed: %v", err) // includes 'merge object data: <inner>'
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before PATCH: confirm the object exists and decodes
obj, err := client.Data().Getter().WithClassName(class).WithID(id).Do(ctx)
if err != nil || obj == nil { return fmt.Errorf("cannot patch %s/%s: %v", class, id, err) }

Type guard

func mergeableProps(obj map[string]interface{}) bool {
    for k, v := range obj {
        switch v.(type) {
        case nil, string, bool, float64, int64, []interface{}, map[string]interface{}:
        default:
            fmt.Printf("unsupported stored property type for %q: %T\n", k, v)
            return false
        }
    }
    return true
}

Try / catch

if err := mergeObject(ctx, class, id, patch); err != nil {
    if strings.Contains(err.Error(), "merge object data") {
        log.Warnf("merge overlay failed, falling back to full replace: %v", err)
        return replaceObjectFully(ctx, class, id, patch)
    }
    return err
}

Prevention

When it happens

Trigger: Calling PATCH /v1/objects/{class}/{id} (or the batch merge path) on an existing object whose stored properties cannot be cleanly overlaid, e.g. stored Properties() is neither nil nor map[string]interface{}, or an inconsistent stored object causes the overlay of PrimitiveSchema/References/Vectors to fail.

Common situations: Objects written by older Weaviate versions with a legacy on-disk property layout being merged by a newer version; corrupted or hand-migrated LSM object data; concurrent writes leaving a torn previous object state.

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/a69a7707af7f2c29. Report an issue: GitHub.