homebridge/homebridge · error · StatusResponseError
Failed to set level with on/off: ${message}
Error message
Failed to set level with on/off: ${message} What it means
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: '.
Source
Thrown at src/matter/behaviors/LevelControlBehavior.ts:201
// command fails, after the plugin's handler has already run (#3993).
// HomebridgeOnOffServer reports the coupled change to the cache instead.
await super.moveToLevelWithOnOff(request)
// Sync level state to cache
registry.syncStateToCache(endpointId, 'levelControl', {
currentLevel: request.level,
})
} 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 set level with on/off: ${message}`, Status.Failure)
}
}
}
View on GitHub (pinned to edf5493034)
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.
Example fix
// before
async moveToLevelWithOnOff(level, fade) {
await this.device.setLevel(level) // device is off, call throws
}
// after
async moveToLevelWithOnOff(level, fade) {
if (!(await this.device.isOn())) await this.device.powerOn()
await this.device.setLevel(level)
} Defensive patterns
Strategy: try-catch
Validate before calling
// Plugin-side, before combined on+level:
const powered = await this.device.isOn().catch(() => false)
const clamped = Math.min(Math.max(Number(level) || 0, 1), this.maxLevel ?? 100)
if (!powered && !this.capabilities.canPowerOnWithLevel) {
throw new StatusResponseError('Cannot set level while off', Status.Failure)
} Type guard
const isStatusResponseError = (e: unknown): e is StatusResponseError => e instanceof StatusResponseError
Try / catch
try {
await homeKit.setBrightness(accessoryId, level) // may include implicit power-on
} catch (e) {
if (e instanceof StatusResponseError && e.message.startsWith('Failed to set level with on/off: ')) {
log.error('combined on+level failed, cause: %s', e.message.slice('Failed to set level with on/off: '.length))
}
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to set level: ${message}
- Failed to move level: ${message}
- Failed to step level: ${message}
- Failed to stop level change: ${message}
- Failed to stop closure: ${message}
AI-assisted analysis of homebridge/homebridge@edf5493034 (2026-08-30).
Data as JSON: /api/errors/29134276fa1e0e29.
Report an issue: GitHub.