This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git

commit b34a8eb67587d2053ad5e7f95ed99fcb28df8d9c
Author: Andrus Adamchik <[email protected]>
AuthorDate: Sun Aug 30 18:54:11 2026 -0400

    Making MCP pref tree management more robust
---
 .../org/apache/cayenne/mcp/tools/openproject/HandshakeWatcher.java | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git 
a/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/openproject/HandshakeWatcher.java
 
b/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/openproject/HandshakeWatcher.java
index 842589db6..4a5054069 100644
--- 
a/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/openproject/HandshakeWatcher.java
+++ 
b/cayenne-mcp-server/src/main/java/org/apache/cayenne/mcp/tools/openproject/HandshakeWatcher.java
@@ -135,6 +135,11 @@ class HandshakeWatcher {
      * Removes handshake subnodes whose {@code startedAt} is older than {@link 
#STALE_NODE_TTL}.
      * Belt-and-suspenders cleanup against an MCP server that crashed between 
launching
      * the Modeler and reading the handshake.
+     * <p>
+     * A node with no readable {@code startedAt} is left alone: it is either a 
Modeler that is
+     * mid-write on its own nonce, or a value that is not visible in this 
process yet (the macOS
+     * CFPreferences store is shared by all JVMs of the user and refreshes 
asynchronously).
+     * Deleting those would kill a concurrent launch's handshake.
      */
     private static void pruneStaleSiblings(PrefsLocator locator) {
         if (!locator.handshakeRootNodeExists()) {
@@ -147,7 +152,7 @@ class HandshakeWatcher {
             for (String child : parent.childrenNames()) {
                 Preferences childNode = parent.node(child);
                 String startedAt = childNode.get("startedAt", null);
-                if (startedAt == null || isBefore(startedAt, cutoff)) {
+                if (startedAt != null && isBefore(startedAt, cutoff)) {
                     childNode.removeNode();
                 }
             }

Reply via email to