From 687200c4dd5afa6aa1d86c5739aaf1114ca8c062 Mon Sep 17 00:00:00 2001 From: Sebastian Lorenz Date: Sat, 1 Aug 2026 18:57:05 +0000 Subject: [PATCH 1/2] Add reproduction for Trie issue --- packages/effect/test/Trie.test.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/effect/test/Trie.test.ts b/packages/effect/test/Trie.test.ts index f3e25d39872..365798e27a3 100644 --- a/packages/effect/test/Trie.test.ts +++ b/packages/effect/test/Trie.test.ts @@ -368,6 +368,16 @@ describe("Trie", () => { assertSome(Trie.longestPrefixOf(trie, "shellsort"), ["shells", 0]) }) + it("longestPrefixOf ignores valued sibling nodes that do not match the input", () => { + const trie = Trie.make(["a", 1], ["b", 2]) + + strictEqual( + Option.isNone(Trie.longestPrefixOf(trie, "c")), + true, + "a non-matching sibling must not be reported as a prefix" + ) + }) + it("map transforms values and can use keys", () => { const trie = Trie.empty().pipe( Trie.insert("shells", 0), From acc9713f60d8df6ed54dfdb845dfbc31108716c8 Mon Sep 17 00:00:00 2001 From: Tim Smart Date: Mon, 3 Aug 2026 11:24:13 +1200 Subject: [PATCH 2/2] Fix Trie longest prefix sibling matching --- .changeset/fix-trie-longest-prefix.md | 5 +++++ packages/effect/src/internal/trie.ts | 7 +++---- 2 files changed, 8 insertions(+), 4 deletions(-) create mode 100644 .changeset/fix-trie-longest-prefix.md diff --git a/.changeset/fix-trie-longest-prefix.md b/.changeset/fix-trie-longest-prefix.md new file mode 100644 index 00000000000..bf422ac6d4e --- /dev/null +++ b/.changeset/fix-trie-longest-prefix.md @@ -0,0 +1,5 @@ +--- +"effect": patch +--- + +Fix `Trie.longestPrefixOf` returning a valued sibling that does not match the input key. diff --git a/packages/effect/src/internal/trie.ts b/packages/effect/src/internal/trie.ts index 6cccc73172f..e003b575551 100644 --- a/packages/effect/src/internal/trie.ts +++ b/packages/effect/src/internal/trie.ts @@ -693,10 +693,6 @@ export const longestPrefixOf = dual< let cIndex = 0 while (cIndex < key.length) { const c = key[cIndex] - if (n.value !== undefined) { - longestPrefixNode = Option.some([key.slice(0, cIndex + 1), n.value.value]) - } - if (c > n.key) { if (n.right === undefined) { break @@ -710,6 +706,9 @@ export const longestPrefixOf = dual< n = n.left } } else { + if (n.value !== undefined) { + longestPrefixNode = Option.some([key.slice(0, cIndex + 1), n.value.value]) + } if (n.mid === undefined) { break } else {