Prerelease This site documents an alpha of libtmux. Its structure, URLs and APIs are subject to change.

Edit this page on GitHub

A command can fail because tmux rejects it, or because the transport stops before returning a reply. Ports report these failures through typed exceptions or return values. Before retrying a mutation, determine whether tmux may already have received it.

For lookup failures caused by zero or multiple matches, see Filtering and queries.

A failed command, as a valueLink to section

PortHow it failsBase type
PythonthrowsLibTmuxException: carries an optional subcommand; str() reads "<subcommand>: <stderr>"
TypeScriptthrowsLibTmuxException extends Error, with TmuxCommandError (tmux ran and refused) and TmuxTransportError (it didn’t get an answer) as the two shapes that matter here
Goreturns (T, error)no shared base type: small typed ...Error structs plus sentinel errors.New values, composed with errors.Is / errors.As and %w wrapping
Rustreturns Result<T, Error>one Error enum, #[non_exhaustive], matched rather than caught
Javathrows (unchecked)LibTmuxException extends RuntimeException
.NETthrowsLibTmuxException, with typed subclasses per failure (TmuxCommandException, TmuxTransportException, TmuxObjectNotFoundException, and a dozen more)
C++returns expected<T, CommandFailure>CommandFailure { kind, delivery, exit_code, diagnostic }: no exception type at all
Swiftthrows (typed)enum TmuxError: Error, thrown as throws(TmuxError): Swift’s typed-throws syntax, not a bare throws

Rust and C++ return result values. Go returns an error that callers inspect with errors.Is or errors.As. Exception-based ports report failures through their exception hierarchies.

TypeScript’s own docs make the split between its two exception shapes concrete:

Is it safe to retry?Link to section

Retry a mutation automatically only when you know it was not dispatched, or when repeating it is safe for your operation. A timeout, cancellation, or dropped connection can occur after tmux has acted. These APIs expose delivery information:

PortNameStates
TypeScriptTmuxTransportError.delivery"not_started" / "written" / "replied" / "indeterminate": only not_started is safe to retry blindly
.NETLibTmuxException.Dispatch (TmuxDispatchState)NotDispatched / Dispatched / Unknown (the default)
JavaDispatchOutcome, via TmuxTimeoutException.outcome()NOT_DISPATCHED / COMPLETE / UNKNOWN
C++DeliveryStatusnot_started / written / replied / indeterminate
RustControlModeErrorKind (behind the control-mode feature)DispatchTimedOut (safe to retry) vs. plain TimedOut (not: the connection may have already committed the command)
Python, Go’s one-shot path-inspect the exit status after normal completion; an interrupted call needs separate state verification
Go’s control-mode poolhandled internally, not exposeda failed pooled connection is retired rather than reused, rather than handing the caller a retry-safety flag to check
Swiftdocumented, not typedControlSession’s own doc comment states the same rule in prose (“a command that never reached tmux is safe to retry”) without a dedicated enum

A state such as not_started, NotDispatched, NOT_DISPATCHED, or DispatchTimedOut identifies a request that did not reach tmux. Treat unknown delivery as potentially executed. C++ and TypeScript also distinguish written, where the transport accepted the request but no terminal reply has arrived.

For subprocess calls that complete normally, inspect the exit status. If a call is interrupted or times out without a delivery state, check tmux’s resulting state before repeating a mutation.

Esc

Type to search.