{"record":{"id":"cf428320eae6e2e9","repo":"weaviate/weaviate","slug":"check-insert-update-status","errorCode":null,"errorMessage":"check insert/update status","messagePattern":"check insert/update status","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"adapters/repos/db/shard_write_merge.go","lineNumber":186,"sourceCode":"\t\t\treturn errors.Wrap(err, \"get bucket\")\n\t\t}\n\n\t\tif prevObj == nil {\n\t\t\treturn errObjectNotFound\n\t\t}\n\n\t\tobj, _, err = s.mergeObjectData(prevObj, merge)\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"merge object data\")\n\t\t}\n\n\t\t// A property-only merge carries the previous version's vectors forward;\n\t\t// a dropped one must not be re-persisted into a new segment.\n\t\tstripDroppedVectors(class, obj)\n\n\t\tstatus, err = s.determineInsertStatus(prevObj, obj)\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"check insert/update status\")\n\t\t}\n\n\t\tobj.DocID = status.docID\n\t\tif status.skipUpsert {\n\t\t\treturn nil\n\t\t}\n\n\t\tobjBytes, err := obj.MarshalBinaryDisk(s.index.Config.SkipWriteClassNameOnDisk)\n\t\tif err != nil {\n\t\t\treturn errors.Wrapf(err, \"marshal object %s to binary\", obj.ID())\n\t\t}\n\n\t\tif err := s.upsertObjectDataLSM(bucket, idBytes, objBytes, status.docID); err != nil {\n\t\t\treturn errors.Wrap(err, \"upsert object data\")\n\t\t}\n\n\t\t// Tee before hashtree: the bucket is the SSOT for movement catchup.\n\t\t// This path does NOT funnel through putObjectLSM, so it needs its own tee.","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/adapters/repos/db/shard_write_merge.go#L168-L204","documentation":"Wrapper around s.determineInsertStatus(prevObj, obj) in mergeObjectInStorage. determineInsertStatus compares the previous and merged object to decide whether the doc ID must be bumped, whether the object changed at all (skipUpsert), and to assign the new DocID. A failure means the shard could not compute the insert/update status for the merged object.","triggerScenarios":"PATCH merge of an existing object where the status computation (doc-ID allocation / change detection between previous and next object) returns an error, e.g. inconsistencies in the stored object that defeat the before/after comparison.","commonSituations":"Data inconsistency after failed writes or crashes mid-segment-flush; objects imported through replication paths with mismatched doc IDs.","solutions":["Inspect the inner error to identify why status determination failed","Confirm the object is consistent with a GET; re-create the object if it appears torn","Retry the merge; transient LSM state usually resolves after a flush","If reproducible, report/upgrade — this indicates internal state the API user cannot fix directly"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// ensure the object is stable/readable before merging\nif _, err := fetchObjectBytID(ctx, class, id); err != nil {\n    return fmt.Errorf(\"object %s not readable, abort merge: %v\", id, err)\n}","typeGuard":null,"tryCatchPattern":"err := mergeObject(ctx, class, id, patch)\nif err != nil && strings.Contains(err.Error(), \"check insert/update status\") {\n    // transient internal state: retry once after a short delay\n    time.Sleep(500 * time.Millisecond)\n    err = mergeObject(ctx, class, id, patch)\n}\nreturn err","preventionTips":["Avoid concurrent PATCH and vector updates on the same object ID","Retry transient merge failures with backoff","Monitor shard health; inconsistent status detection often follows crashes","Report persistent occurrences — this points to internal state corruption"],"tags":["go","storage","merge","docid"],"backgroundTag":"object-merge-failed","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}