{"record":{"id":"fa1abe19164993c7","repo":"apache/pulsar","slug":"failed-to-update-from-old-s-to-value-s","errorCode":null,"errorMessage":"Failed to update from old:%s to value:%s","messagePattern":"Failed to update from old:(.+?) to value:(.+?)","errorType":"exception","errorClass":"ConflictException","httpStatus":null,"severity":"error","filePath":"pulsar-metadata/src/main/java/org/apache/pulsar/metadata/tableview/impl/MetadataStoreTableViewImpl.java","lineNumber":412,"sourceCode":"    private String getKey(String path) {\n        return path.replaceFirst(pathPrefix + \"/\", \"\");\n    }\n\n    public boolean exists(String key) {\n        return immutableData.containsKey(key);\n    }\n\n    public T get(String key) {\n        return data.get(key);\n    }\n\n    public CompletableFuture<Void> put(String key, T value) {\n        String path = getPath(key);\n        return cache.readModifyUpdateOrCreate(path, (old) -> {\n            if (conflictResolver.test(old.orElse(null), value)) {\n                return value;\n            } else {\n                throw new ConflictException(\n                        String.format(\"Failed to update from old:%s to value:%s\", old, value));\n            }\n        }).thenCompose(__ -> doHandleNotification(path)) // immediately notify local tableview\n        .exceptionally(e -> {\n            if (e.getCause() instanceof MetadataStoreException.BadVersionException) {\n                throw FutureUtil.wrapToCompletionException(new ConflictException(\n                        String.format(\"Failed to update to value:%s\", value)));\n            }\n\n            throw FutureUtil.wrapToCompletionException(e.getCause());\n        });\n    }\n\n    public CompletableFuture<Void> delete(String key) {\n        String path = getPath(key);\n        return cache.delete(path)\n                .thenCompose(__ -> doHandleNotification(path)); // immediately notify local tableview\n    }","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-metadata/src/main/java/org/apache/pulsar/metadata/tableview/impl/MetadataStoreTableViewImpl.java#L394-L430","documentation":"ConflictException thrown by MetadataStoreTableViewImpl.put when the configured conflictResolver rejects the update: the resolver test(oldValue, newValue) returned false, so the read-modify-update on the cached entry is aborted with this formatted message showing old and new values.","triggerScenarios":"Calling tableview.put(key, value) where the existing value (or null when absent) fails the ConflictResolver predicate supplied at tableview construction, e.g. a resolver that requires monotonically increasing values receives an older value.","commonSituations":"Out-of-order writes from a producer applying stale state, concurrent writers fighting over the same key with a last-writer-loses-resolver rejecting, or putting a value that violates domain rules encoded in the resolver.","solutions":["Make the value pass the conflictResolver you configured, or adjust the resolver logic to accept the transition.","Check the old value in the message to see why the transition was rejected (e.g. version/ordering regression).","If the write is legitimate after a restart or state reset, delete the key first or seed the resolver with correct baseline state.","Handle ConflictException from the returned CompletableFuture and re-read the current tableview state before retrying."],"exampleFix":"// before\n.resolveConflict((old, next) -> next >= old)  // rejects stale lower values\n// after\n.resolveConflict((old, next) -> next >= old || isReset(next))","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"tableView.put(key, value).exceptionally(ex -> {\n    Throwable c = FutureUtil.unwrapCompletionException(ex);\n    if (c instanceof ConflictException) {\n        // re-read state via tableview.get(key), reconcile, retry\n    }\n    throw ex instanceof RuntimeException ? (RuntimeException) ex : new RuntimeException(ex);\n});","preventionTips":["Design the conflictResolver to accept legitimate state transitions including restarts.","Log old/new values from the ConflictException message for diagnosis.","Avoid concurrent writers to the same tableview key; assign per-key ownership.","Reconcile local state with the store before retrying rejected writes."],"tags":["conflict","tableview","concurrency","metadata-store"],"backgroundTag":"write-conflict","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}