From 732548d92ce0fa4a1e7ab366ea4f37f24e6af628 Mon Sep 17 00:00:00 2001 From: Ingo Fischer Date: Sun, 30 Aug 2026 22:03:29 +0200 Subject: [PATCH] test(node): pin the one path that reaches an absent fabric-scoped list An optional fabric-scoped attribute holding no value is not advertised -- ValidatedElements decides support by whether state holds a value, so it stays out of AttributeList and a peer write is declined as unsupported. The only way to reach the member is the server's own code writing into it, which has no session to supply the fabric. Before conformance resolved through the base, such a write was accepted and stored an entry belonging to no fabric, unusable to anyone reading it. It is now refused and the member is left absent. Co-Authored-By: Claude Opus 5 (1M context) --- .../state/managed/values/ListManagerTest.ts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/node/test/behavior/state/managed/values/ListManagerTest.ts b/packages/node/test/behavior/state/managed/values/ListManagerTest.ts index 43cd86c771..85dcc70763 100644 --- a/packages/node/test/behavior/state/managed/values/ListManagerTest.ts +++ b/packages/node/test/behavior/state/managed/values/ListManagerTest.ts @@ -5,6 +5,7 @@ */ import { ActionContext } from "#behavior/context/ActionContext.js"; +import { LocalActorContext } from "#behavior/context/server/LocalActorContext.js"; import { MaybePromise } from "@matter/general"; import { ConformanceError, Val } from "@matter/protocol"; import { FabricIndex, NodeId } from "@matter/types"; @@ -576,6 +577,22 @@ describe("ListManager", () => { }, {}); }); + // A behavior populating a fabric-scoped attribute at startup has no session, so nothing supplies the fabric + it("refuses an entry stored with no session to supply the fabric", async () => { + const struct = TestStruct( + { list: listOf(structOf({ fabricIndex: "FabricIndex", value: "uint8" }), { access: "F" }) }, + {}, + ); + + await LocalActorContext.act("test", async cx => { + const ref = struct.reference(cx); + expect(() => (ref.list = [{ value: 1 }])).throw(ConformanceError); + expect(ref.list).undefined; + }); + + expect(struct.fields.list).undefined; + }); + it("supplies the accessing fabric for an entry that omits it", async () => { await testMandatoryFabricIndex(list => { list[0] = { value: 3 };