Skip to content

CommodityTariff.DayEntryStruct.RandomizationType has both default: 0 and conformance [RNDM], so setStateOf() rejects its own auto-fill #4374

Description

@lboue

matter.js version

0.17.9

Node.js version

v24.18.0

Operating system

Ubuntu Linux 6.17.0-35-generic, x86_64

Description

What I did:
Built a CommodityTariff cluster server (feature Pricing only, Randomization NOT enabled) on an
endpoint, then used endpoint.setStateOf(CommodityTariffServer, { dayEntries: [...], ... }) (via
Matterbridge's setAttribute() helper) to publish a flat-rate day schedule after the endpoint was
already installed/active. The dayEntries value was:

dayEntries: [{ dayEntryId: 1, startTime: 0 }]

i.e. a plain DayEntryStruct with only the two mandatory fields (DayEntryId, StartTime) — no
RandomizationOffset/RandomizationType key at all.

What I expected:
The write to succeed, since RandomizationType's conformance ([RNDM]) means the field must be
absent when the Randomization feature isn't enabled — and I never supplied it.

What happened:
The write is rejected:

Validating Matterbridge.Matterbridge.electricalMeter1.electricalMeterCurrent.commodityTariff.state.0.randomizationType:
Conformance "[RNDM]": Matter does not allow you to set this attribute (135)

Full stack trace (from the attached log, matterbridge-commoditytariff-bug.log):

Error: Validating Matterbridge.Matterbridge.electricalMeter1.electricalMeterCurrent.commodityTariff.state.0.randomizationType: Conformance "[RNDM]": Matter does not allow you to set this attribute (135)
    at disallowValue (file:///.../node_modules/@matter/node/dist/esm/behavior/state/validation/conformance-compiler.js:432:13)
    at Object.randomizationType (file:///.../node_modules/@matter/node/dist/esm/behavior/state/validation/conformance.js:20:19)
    at validateStruct (file:///.../node_modules/@matter/node/dist/esm/behavior/state/validation/ValueValidator.js:275:23)
    at file:///.../node_modules/@matter/node/dist/esm/behavior/state/validation/ValueValidator.js:30:7
    at file:///.../node_modules/@matter/node/dist/esm/behavior/state/validation/conformance.js:28:22
    at validateEntries (file:///.../node_modules/@matter/node/dist/esm/behavior/state/validation/ValueValidator.js:320:11)
    ...

Analysis:
Looking at the Matter model source (@matter/model/src/standard/elements/commodity-tariff.element.ts):

Field({ name: "RandomizationOffset", id: 0x3, type: "int16", conformance: "[RNDM]" }),
Field({
    name: "RandomizationType", id: 0x4, type: "DayEntryRandomizationTypeEnum", conformance: "[RNDM]",
    default: 0
})

RandomizationType is declared with both:

  • conformance: "[RNDM]" — the field must be entirely absent unless the Randomization feature is
    enabled (which I don't have — only Pricing).
  • default: 0 — an unconditional default value.

When the write path (endpoint.setStateOf() → the attribute-server validated write, as opposed to
behaviors.require()'s initial-injection path, which does not hit this) canonicalizes the partial
DayEntryStruct I supplied against the full model, it fills the missing randomizationType key with
its declared default (0) — and then the conformance validator rejects that very same auto-filled
value for violating the [RNDM] gate. The model's own default-filling and its own conformance rule
contradict each other for any consumer that doesn't enable Randomization.

Confirmed this only affects the list-attribute write path: writing a single DayEntryStruct
attribute (e.g. currentDayEntry) with the exact same shape ({ dayEntryId, startTime }) succeeds
without error — only dayEntries (List[DayEntryStruct]) triggers the crash. So the bug is specific
to how struct defaults are filled/validated for list-attribute elements versus a bare struct attribute.

Proposed fix (not verified against the codebase, just a hypothesis):
Either:

  1. RandomizationType/RandomizationOffset should have no default in the model (leave them
    undefined when absent, so canonicalization doesn't synthesize a value that then fails its own
    conformance check), or
  2. the conformance validator should treat an auto-filled default value for a [FEATURE]-gated
    optional field as "absent" rather than "set", when the caller never supplied it explicitly, or
  3. struct defaulting inside List[Struct] attribute writes should follow the same (working) code path
    used for a bare struct attribute write.

Full log attached (matterbridge-commoditytariff-bug.log, ~1300 lines): covers plugin/endpoint
construction, the three preceding successful setAttribute() calls (tariffInfo, tariffUnit,
startDate — all succeed), the failing dayEntries write, the rollback, and the full stack trace.
Reached through Matterbridge (a wrapper around matter.js), but the failing call is a plain
endpoint.setStateOf(CommodityTariffServer, { dayEntries: [...] }) — no Matterbridge-specific logic is
involved in the failure itself.
matterbridge-commoditytariff-bug.log

Confirmation

  • I attached a complete log file (not just a few quoted lines) covering the context around the problem.
  • Any analysis of behavior or log output in my description — whether written by me or by an AI tool — is backed by that attached log.
  • I have reviewed and understand everything in this report and can explain it in my own words (AI policy).
  • I searched existing issues and this is not a duplicate.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions