#3996·homebridge

Matter: external accessories ignore plugin-supplied manufacturer and model (BasicInformation always reports 'Homebridge')

Author: mathiashornbekCreated Aug 21, 2026Updated Aug 21, 2026

Describe the bug

For external Matter accessories, accessory.manufacturer and accessory.model are collected, passed into the dedicated MatterServer, validated, sanitized and returned by the config layer — and then never read. The node's BasicInformation cluster gets a hardcoded vendorName: 'Homebridge' and a productName derived from displayName.

The effect a user sees in Apple Home, on the accessory details page of a plugin-provided external Matter accessory:

Row Shows Should show
Manufacturer Homebridge accessory.manufacturer
Model the accessory's name accessory.model

Bridged Matter accessories are correct — AccessoryManager.createEndpointOptions() maps both fields onto bridgedDeviceBasicInformation. Only the external/standalone server path drops them.

The path, in v2.4.0

  1. src/matter/ExternalMatterAccessoryPublisher.ts:100-101 passes them in:
    manufacturer: accessory.manufacturer,
    model: accessory.model,
    
  2. src/matter/server/ServerConfig.ts:64-73 validates and truncates both, and :106-107 returns them in the resolved config:
    let manufacturer = config.manufacturer
    if (manufacturer !== undefined) {
      manufacturer = truncateString(manufacturer, 32, 'Manufacturer name').value
    }
    
  3. src/matter/server/ServerLifecycle.ts:319-326 builds basicInformation without reading either one:
    nodeLabel: displayName.slice(0, 32),
    vendorId: VendorId(deps.commissioningManager.vendorId),
    vendorName: DEFAULT_BRIDGE_DEFAULTS.vendorName,     // <- always 'Homebridge'
    productId: deps.commissioningManager.productId,
    productName: displayName.slice(0, 32),              // <- name, not model
    productLabel: (stripVendorFromLabel(displayName, DEFAULT_BRIDGE_DEFAULTS.vendorName) || 'Bridge').slice(0, 64),
    

config.manufacturer and config.model have no other reader anywhere under src/matter/. The truncation limits in ServerConfig (32 chars for each) are exactly the BasicInformation constraints for VendorName/ProductName, so the intent to use them there seems clear — the wiring is just missing.

Suggested fix

vendorName: deps.config.manufacturer || DEFAULT_BRIDGE_DEFAULTS.vendorName,
productName: (deps.config.model || displayName).slice(0, 32),
productLabel: (stripVendorFromLabel(displayName, deps.config.manufacturer || DEFAULT_BRIDGE_DEFAULTS.vendorName) || deps.config.model || 'Device').slice(0, 64),

Note this mirrors the bridged path, which already falls back to accessory.model for productLabel when stripping the vendor consumes the whole name.

Two things worth deciding rather than assuming:

  • vendorId stays as-is. It has to: an uncertified plugin cannot claim a real Matter vendor ID, and vendorName is a free-text string with no relationship to it. Changing only the name is spec-legal.
  • Changing BasicInformation on an already-commissioned node is an attribute write, not a structural change, so it should not need re-commissioning — but a controller that cached the old strings may keep showing them until it re-reads. Worth a line in the release notes either way.

To Reproduce

  1. A platform plugin that registers a Matter accessory as external, setting accessory.manufacturer and accessory.model.
  2. Pair it with Apple Home.
  3. Open the accessory's settings → the Manufacturer row reads Homebridge and the Model row reads the accessory's name.

Reproduced on two unrelated households running homebridge-roborock-matter, which sets accessory.manufacturer = 'Roborock' on every robot; both show Homebridge. Log line confirming the external path:

[Matter/External] ✓ External Matter accessory published: <name> on port 5534 (bridge XX:XX:XX:XX:XX:XX)

Expected behavior

An external Matter accessory reports the manufacturer and model its plugin supplied, the same way a bridged one already does.

Homebridge Version

v2.4.0

Node.js Version

v24.19.0

Operating System

Ubuntu 26.04 LTS (also observed on a separate installation)