{"record":{"id":"29134276fa1e0e29","repo":"homebridge/homebridge","slug":"failed-to-set-level-with-on-off-message","errorCode":null,"errorMessage":"Failed to set level with on/off: ${message}","messagePattern":"Failed to set level with on/off: (.+?)","errorType":"exception","errorClass":"StatusResponseError","httpStatus":null,"severity":"error","filePath":"src/matter/behaviors/LevelControlBehavior.ts","lineNumber":201,"sourceCode":"      // command fails, after the plugin's handler has already run (#3993).\n      // HomebridgeOnOffServer reports the coupled change to the cache instead.\n      await super.moveToLevelWithOnOff(request)\n\n      // Sync level state to cache\n      registry.syncStateToCache(endpointId, 'levelControl', {\n        currentLevel: request.level,\n      })\n    } catch (error) {\n      // If user handler already threw a StatusResponseError, propagate it as-is\n      // This sends a proper Matter protocol error response to the controller\n      if (MatterStatus.isMatterProtocolError(error)) {\n        throw error\n      }\n\n      // For other errors, wrap in appropriate StatusResponseError\n      // This prevents the endpoint from crashing and keeps the device online\n      const message = error instanceof Error ? error.message : String(error)\n      throw new StatusResponseError(`Failed to set level with on/off: ${message}`, Status.Failure)\n    }\n  }\n}\n","sourceCodeStart":183,"sourceCodeEnd":205,"githubUrl":"https://github.com/homebridge/homebridge/blob/edf54930340d67cade23d01abd41b03cd9621e8b/src/matter/behaviors/LevelControlBehavior.ts#L183-L205","documentation":"Thrown by HomebridgeLevelControlServer.moveToLevelWithOnOff when the plugin-registered handler for MoveToLevelWithOnOff throws an unexpected error. The error is wrapped in StatusResponseError with Status.Failure so the Matter endpoint remains online and the controller gets a protocol failure. The underlying message follows 'Failed to set level with on/off: '.","triggerScenarios":"Controller sends MoveToLevelWithOnOff (brightness slider on an off bulb - turns it on while setting level); the plugin's registered handler throws/rejects with a non-Matter error such as a failed power-on sequence or TypeError. StatusResponseErrors from the handler pass through unwrapped.","commonSituations":"Handler must power the device on before setting level and the power call fails; combined on+level device API returns partial success then throws; plugin logic bug when onOff state is stale in its cache; Siri sets brightness on a switched-off light.","solutions":["Read the text after 'Failed to set level with on/off: ' for the plugin handler's root-cause error.","Fix the handler's on+level sequence: ensure power-on is awaited and both device calls are individually try/catch-wrapped.","Throw StatusResponseError from the handler for domain failures to control the Matter status returned.","Verify the device is online and responsive, then retry from the controller.","Update the plugin or file an issue if the wrapped message reveals an internal bug."],"exampleFix":"// before\nasync moveToLevelWithOnOff(level, fade) {\n  await this.device.setLevel(level) // device is off, call throws\n}\n\n// after\nasync moveToLevelWithOnOff(level, fade) {\n  if (!(await this.device.isOn())) await this.device.powerOn()\n  await this.device.setLevel(level)\n}","handlingStrategy":"try-catch","validationCode":"// Plugin-side, before combined on+level:\nconst powered = await this.device.isOn().catch(() => false)\nconst clamped = Math.min(Math.max(Number(level) || 0, 1), this.maxLevel ?? 100)\nif (!powered && !this.capabilities.canPowerOnWithLevel) {\n  throw new StatusResponseError('Cannot set level while off', Status.Failure)\n}","typeGuard":"const isStatusResponseError = (e: unknown): e is StatusResponseError => e instanceof StatusResponseError","tryCatchPattern":"try {\n  await homeKit.setBrightness(accessoryId, level) // may include implicit power-on\n} catch (e) {\n  if (e instanceof StatusResponseError && e.message.startsWith('Failed to set level with on/off: ')) {\n    log.error('combined on+level failed, cause: %s', e.message.slice('Failed to set level with on/off: '.length))\n  }\n}","preventionTips":["Power the device on explicitly before setting level if the device cannot do combined commands.","Validate and clamp the level argument at the top of the handler.","Await both the power-on and level calls; never fire-and-forget.","Keep onOff state cache synced so the handler does not act on stale state.","Test brightness-on-off-bulb flows (MoveToLevelWithOnOff) explicitly."],"tags":["matter","level-control","move-to-level-with-onoff","plugin-handler","status-response-error"],"backgroundTag":"matter-command-handler-failed","analyzedSha":"edf54930340d67cade23d01abd41b03cd9621e8b","analyzedAt":"2026-08-30T21:28:53.235Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}