homebridge/homebridge · error · StatusResponseError

Status.Failure

Status.Failure

Error message

Failed to open window covering: ${message}

What it means

StatusResponseError (Status.Failure) thrown by HomebridgeWindowCoveringServer.upOrOpen when the plugin's registered 'upOrOpen' handler throws a non-Matter error. The wrapper keeps the Matter endpoint alive and returns a protocol-level FAILURE to the controller, with the underlying error message appended. Genuine Matter protocol errors from the handler pass through untouched.

Source

Thrown at src/matter/behaviors/WindowCoveringBehavior.ts:110

      await super.upOrOpen()

      // Sync state to cache - window covering opening
      this.syncPositionStateToCache(
        endpointId,
        WindowCoveringStateProps.targetPositionLiftPercent100ths,
        WindowCoveringStateProps.currentPositionLiftPercent100ths,
      )
    } catch (error) {
      // If user handler already threw a StatusResponseError, propagate it as-is
      // This sends a proper Matter protocol error response to the controller
      if (MatterStatus.isMatterProtocolError(error)) {
        throw error
      }

      // For other errors, wrap in appropriate StatusResponseError
      // This prevents the endpoint from crashing and keeps the device online
      const message = error instanceof Error ? error.message : String(error)
      throw new StatusResponseError(`Failed to open window covering: ${message}`, Status.Failure)
    }
  }

  override async downOrClose(): Promise<void> {
    const endpointId = this.endpoint.id
    const registry = this.getRegistry()

    try {
      // Execute user handler
      await registry.executeHandler(endpointId, 'windowCovering', 'downOrClose')

      // Only reached if handler succeeded - update Matter state
      await super.downOrClose()

      // Sync state to cache - window covering closing
      this.syncPositionStateToCache(
        endpointId,
        WindowCoveringStateProps.targetPositionLiftPercent100ths,

View on GitHub (pinned to edf5493034)

Solutions

  1. Read the detail after 'Failed to open window covering:' in the log to find the real cause
  2. Confirm the shade/blind device is online and controllable via the plugin's own app/API
  3. Update or fix the plugin; in your own plugin, throw StatusResponseError from handlers for expected device failures so controllers get specific Matter statuses
  4. Restart the bridge/plugin after resolving the device-side issue

Example fix

// before
async upOrOpen() { await shadeApi.open() }
// after
async upOrOpen() {
  if (!shadeApi.connected) throw new StatusResponseError('shade offline', Status.Failure)
  await shadeApi.open()
}
Defensive patterns

Strategy: try-catch

Validate before calling

registry.registerHandler(endpointId, 'windowCovering', 'upOrOpen', async () => {
  if (!shade.reachable) throw new StatusResponseError('shade unreachable', Status.Failure)
})

Type guard

const isStatusResponseError = (e: unknown): e is StatusResponseError => e instanceof StatusResponseError

Try / catch

try { await sendUpOrOpen() }
catch (e) {
  if (isStatusResponseError(e) && e.message.includes('Failed to open window covering:')) {
    log.error('underlying:', e.message.split(': ').slice(1).join(': '))
  }
}

Prevention

When it happens

Trigger: A controller sends the WindowCovering UpOrOpen command and the plugin's upOrOpen handler rejects — e.g. the blind's motor API errors, times out, or the handler code throws. Also thrown if super.upOrOpen() (internal Matter state update) fails after a successful handler.

Common situations: Cloud-connected shades with expired tokens; local MQTT/HTTP bridge to the shade offline; plugin bug such as referencing an undefined accessory in the handler; race where the shade was removed while a command was in flight.

Related errors


AI-assisted analysis of homebridge/homebridge@edf5493034 (2026-08-30). Data as JSON: /api/errors/4de11d9e514872db. Report an issue: GitHub.