kovidgoyal/kitty · warning
Unknown OSC 9;4 state: {st}
Error message
Unknown OSC 9;4 state: {st} What it means
The terminal sent an OSC 9;4 progress sequence with a state number kitty does not recognize (only 0,1,2,3,4 are valid: remove, set, error, indeterminate, paused). kitty logs the unknown state and ignores the update.
Source
Thrown at kitty/progress.py:45
self.last_update_at = monotonic()
if st == 0:
self.state = ProgressState.unset
self.percent = 0
elif st == 1:
self.state = ProgressState.set
self.percent = max(0, min(percent, 100))
elif st == 2:
self.state = ProgressState.error
self.percent = 0
elif st == 3:
self.state = ProgressState.indeterminate
self.percent = 0
elif st == 4:
self.state = ProgressState.paused
if percent > -1:
self.percent = max(0, min(percent, 100))
else:
log_error(f'Unknown OSC 9;4 state: {st}')
def clear_progress(self) -> bool:
time_since_last_update = monotonic() - self.last_update_at
threshold = self.finished_clear_timeout if self.percent == 100 and self.state is ProgressState.set else self.clear_timeout
if time_since_last_update >= threshold:
self.state = ProgressState.unset
self.percent = 0
return True
return False
View on GitHub (pinned to 6d5d0c4406)
Solutions
- Check the emitted state number and use only 0,1,2,3,4
- Update the library/script emitting the sequence to the documented OSC 9;4 spec
- Ignore: harmless, kitty keeps the last valid progress state
Example fix
# before printf '\e]9;4;6,50\a' # after printf '\e]9;4;1,50\a'
Defensive patterns
Strategy: validation
Validate before calling
def valid_osc94(state, pct):
return state in (0, 1, 2, 3, 4) and (pct == -1 or 0 <= pct <= 100)
# only emit when valid
if valid_osc94(s, p):
printf_osc(f'9;4;{s},{p}') Type guard
is_valid_progress_state = lambda st: isinstance(st, int) and 0 <= st <= 4
Prevention
- Only emit OSC 9;4 states 0-4
- Use libraries like progress or kitty's shell integration instead of raw escapes
When it happens
Trigger: A shell script/program emitting printf '\e]9;4;<state>,<percent>\a' with state outside 0-4, hitting ProgressState update in kitty/progress.py.
Common situations: Hand-rolled progress-bar scripts or a terminal library that emits a non-standard/in newer OSC 9;4 state value.
Related errors
- This must be run as kitten ask
- This should be run as kitten broadcast
- This must be run as kitten choose-files
- Pipe to kitten was broken while sending data to it
- Unknown action: {action}
AI-assisted analysis of kovidgoyal/kitty@6d5d0c4406 (2026-08-27).
Data as JSON: /api/errors/3af9147b242ad978.
Report an issue: GitHub.