Koenkk / Koenkk/zigbee2mqtt

on_time (onWithTimedOff) throws a raw RangeError instead of a clear validation error above 6553.5s

Open Beginner friendly
#32,889 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
15.7k
Forks
2k
Avg merge
18h 55m
Merged PRs (30d)
35

Description

What happened?

When on_time (or off_wait_time) is set to a value that, once converted to tenths of a second, exceeds the ZCL 16-bit limit, Zigbee2MQTT lets an unhandled RangeError [ERR_OUT_OF_RANGE] bubble up from Node's buffer layer instead of validating the input first.

Root cause: the converter simply multiplies seconds by 10 before sending, with no bound check:

{ctrlbits: 0, ontime: Math.round(onTime * 10), offwaittime: Math.round(offWaitTime * 10)}

Since the ZCL OnTime / OffWaitTime fields are uint16, the real ceiling is 6553.5 s (1h49min), not 65535 s as the on_time parameter might suggest.

on_time sent value sent to device result
60 600 1 min OK
1000 10000 16 min 40 s OK
3600 36000 1 h OK
10800 108000 RangeError, since it is > 65535

This is closely related to #25323, which reported the same crash but framed it as wanting the ceiling raised past ~1h49 (not achievable, it's a ZCL protocol limit, not a Z2M bug). The remaining, narrower issue is that Z2M doesn't validate the value before sending it and lets a raw Node error through, unlike similar converters (e.g. toggle_wait_cmd for TS011F_plug_1, which checks the range up front and throws a clear, catchable error).

What did you expect to happen?

A clear, catchable validation error (e.g. "on_time must be between 0 and 6553.5 seconds") instead of an unhandled RangeError originating from the ZCL/buffer layer.

How to reproduce it (minimal and precise)

zigbee2mqtt/<friendly_name>/set

{"state": "ON", "on_time": 10800}

Result:

RangeError [ERR_OUT_OF_RANGE]: ZCL command .../1 genOnOff.onWithTimedOff({"ctrlbits":0,"ontime":108000,"offwaittime":0}, ...) failed (The value of "value" is out of range. It must be >= 0 and <= 65535. Received 108000)
Suggested fix

Add a bound check (0-6553.5s) on on_time / off_wait_time in the shared converter, before calling entity.command('genOnOff', 'onWithTimedOff', ...), mirroring the existing validation pattern used in toggle_wait_cmd.

Zigbee2MQTT version

2.13.0

Adapter

SMLIGHT SLZB-06M

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Read the shared converter that builds the genOnOff onWithTimedOff payload, then compare its range-checking pattern with toggle_wait_cmd. Reproduce the issue with an on_time of 10800 and add focused coverage so values through 6553.5 seconds succeed while larger on_time or off_wait_time values produce a clear, catchable validation error.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
embedded-iot
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.