Migration notes¶

Migration and deprecation notes for libtmux are here, see Changelog as well.

Welcome on board! đź‘‹

  1. 📌 For safety, always pin the package

  2. đź“– Check the migration notes (You are here)

  3. 📣 If you feel something got deprecated and it interrupted you - past, present, or future - voice your opinion on the tracker.

    We want to make libtmux fun, reliable, and useful for users.

    API changes can be painful.

    If we can do something to draw the sting, we’ll do it. We’re taking a balanced approach. That’s why these notes are here!

    (Please pin the package. 🙏)

Complete Deprecation Reference¶

This table provides a quick reference for all deprecated APIs. See version-specific sections below for detailed migration examples and code samples.

Method Renamings¶

Class

Deprecated

Replacement

Since

Raises

Server

kill_server()

kill()

0.30.0 (2024-02-16)

0.51.0

Session

attach_session()

attach()

0.30.0 (2024-02-16)

0.51.0

Session

kill_session()

kill()

0.30.0 (2024-02-16)

0.51.0

Window

select_window()

select()

0.30.0 (2024-02-16)

0.51.0

Window

kill_window()

kill()

0.30.0 (2024-02-16)

0.51.0

Window

split_window()

split()

0.33.0 (2024-03-17)

0.51.0

Window

set_window_option()

set_option()

0.50.0 (2025-11-30)

(warning)

Window

show_window_option()

show_option()

0.50.0 (2025-11-30)

(warning)

Window

show_window_options()

show_options()

0.50.0 (2025-11-30)

(warning)

Pane

select_pane()

select()

0.30.0 (2024-02-16)

0.51.0

Pane

resize_pane()

resize()

0.28.0 (2024-02-14)

0.51.0

Pane

split_window()

split()

0.33.0 (2024-03-17)

0.51.0

Property Renamings¶

Class

Deprecated

Replacement

Since

Raises

Session

attached_window

active_window

0.31.0 (2024-02-17)

0.51.0

Session

attached_pane

active_pane

0.31.0 (2024-02-17)

0.51.0

Window

attached_pane

active_pane

0.31.0 (2024-02-17)

0.51.0

Parameter Changes¶

Method(s)

Deprecated

Replacement

Since

Raises

Options/hooks methods

g

global_

0.50.0 (2025-11-30)

(warning)

split_window() / split()

percent

size

0.28.0 (2024-02-14)

0.51.0

split_window() / split()

vertical/horizontal

direction (PaneDirection)

0.33.0 (2024-03-17)

0.51.0

resize_pane()

-U, -D, -L, -R

adjustment_direction

0.28.0 (2024-02-14)

0.51.0

Server.get_by_id()

id

session_id

0.16.0 (2022-12-10)

0.51.0

Session.get_by_id()

id

window_id

0.16.0 (2022-12-10)

0.51.0

Window.get_by_id()

id

pane_id

0.16.0 (2022-12-10)

0.51.0

Query/Filter API Changes¶

Class

Deprecated

Replacement

Since

Raises

Server

list_sessions() / _list_sessions()

sessions property

0.17.0 (2022-12-26)

0.51.0

Server

where({...})

sessions.filter(**kwargs)

0.17.0 (2022-12-26)

0.51.0

Server

find_where({...})

sessions.get(default=None, **kwargs)

0.17.0 (2022-12-26)

0.51.0

Server

_list_panes() / _update_panes()

panes property

0.17.0 (2022-12-26)

0.51.0

Server

_list_windows() / _update_windows()

windows property

0.17.0 (2022-12-26)

0.51.0

Server

get_by_id(id)

sessions.get(session_id=..., default=None)

0.16.0 (2022-12-10)

0.51.0

Session

list_windows() / _list_windows()

windows property

0.17.0 (2022-12-26)

0.51.0

Session

where({...})

windows.filter(**kwargs)

0.17.0 (2022-12-26)

0.51.0

Session

find_where({...})

windows.get(default=None, **kwargs)

0.17.0 (2022-12-26)

0.51.0

Session

get_by_id(id)

windows.get(window_id=..., default=None)

0.16.0 (2022-12-10)

0.51.0

Window

list_panes() / _list_panes()

panes property

0.17.0 (2022-12-26)

0.51.0

Window

where({...})

panes.filter(**kwargs)

0.17.0 (2022-12-26)

0.51.0

Window

find_where({...})

panes.get(default=None, **kwargs)

0.17.0 (2022-12-26)

0.51.0

Window

get_by_id(id)

panes.get(pane_id=..., default=None)

0.16.0 (2022-12-10)

0.51.0

All

children property

sessions/windows/panes

0.17.0 (2022-12-26)

0.51.0

Attribute Access Changes¶

Pattern

Deprecated

Replacement

Since

Raises

Dict key access

obj['key']

obj.key

0.17.0 (2022-12-26)

0.51.0

Dict get

obj.get('key')

obj.key

0.17.0 (2022-12-26)

0.51.0

Dict get w/ default

obj.get('key', None)

getattr(obj, 'key', None)

0.17.0 (2022-12-26)

0.51.0

Removed Items¶

Item

Removed In

Migration

tmux < 3.2a support

0.49.0 (2025-11-29)

Upgrade tmux or use libtmux 0.48.x

console_to_str()

0.42.0 (2025-02-02)

Use text=True in subprocess

str_from_console()

0.42.0 (2025-02-02)

Use text=True in subprocess

common.which()

0.12.0 (2022-07-13)

Use shutil.which()

Default Behavior Changes¶

Method

Old Default

New Default

Since

Session.new_window()

attach=True

attach=False

0.28.0 (2024-02-14)

Window.split_window()

attach=True

attach=False

0.28.0 (2024-02-14)


Upcoming Release¶

Detailed migration steps for the next version will be posted here.

libtmux 0.57.0: Subcommand-tagged exceptions (#672)¶

LibTmuxException str() gains a subcommand prefix¶

When LibTmuxException is raised from a libtmux method, str(exc) now starts with the originating tmux subcommand name followed by ": ". exc.args[0] still carries the original tmux error text, and the new subcommand attribute exposes the tmux subcommand name on its own.

The error-payload type changed: exc.args[0] is now str, joined with "\n" when tmux emitted multiple stderr lines. Previously it was list[str].

Who is affected: code that pattern-matches str(exc) exactly, anchors a regex with ^ against the previous shape, or indexes exc.args[0] element-by-element expecting a list. Substring containment ("can't find" in str(exc)) and unanchored re.search patterns continue to match unchanged.

Before:

try:
    session.last_window()
except LibTmuxException as exc:
    if str(exc) == "can't find window":
        handle_missing_last_window()

After (0.57.0+) — dispatch on the typed attribute:

try:
    session.last_window()
except LibTmuxException as exc:
    if exc.subcommand == "last-window":
        handle_missing_last_window()

Or — match against the original tmux error text in exc.args[0]:

try:
    session.last_window()
except LibTmuxException as exc:
    if exc.args and exc.args[0] == "can't find window":
        handle_missing_last_window()

Client.session_id / window_id / pane_id are snapshots, not identity¶

Client is new in 0.57.0, so this isn’t a behavior change — but new users of clients should know that client.session_id, client.window_id, and client.pane_id reflect the client’s attached view at the moment the Client was read. They go stale as soon as the client switches sessions, changes window, or detaches.

For typed access that reflects the client’s live attachment, use attached_session, attached_window, and attached_pane:

# Snapshot (may be stale)
client = server.clients.get(client_name=ctl.client_name)
session_id = client.session_id  # str captured when the object was read

# Live (re-reads list-clients; returns None if tmux no longer reports the client)
attached = client.attached_session  # libtmux.Session | None
window = client.attached_window     # libtmux.Window  | None
pane = client.attached_pane         # libtmux.Pane    | None

The client.client_name field (typically the tty path on Unix) is the client’s stable identifier and does not have this caveat. The attached_* properties translate a missing list-clients row into None for convenience; direct refresh() and from_client_name() calls still raise when that client row is gone.

attached_pane follows the attached session’s current window. That can differ from the per-client active pane set by select-pane -P.

Pane.reset now uses one tmux command sequence¶

reset() now bundles send-keys -R and clear-history into one tmux command sequence targeted at the pane. This closes a race where output written between separate commands could land in the scrollback that the second command then cleared.

Who is affected: test fixtures and downstream code that intercepts Pane.cmd (for example with unittest.mock.patch.object(pane, "cmd")) will no longer observe reset()’s tmux invocation. Patch Server.cmd instead, or assert on the resulting pane state directly.

Server.display_message / Window.display_message / Pane.display_message warn instead of raise¶

The three display_message wrappers now report tmux stderr via :func:warnings.warn rather than raising LibTmuxException. tmux uses stderr for both genuine errors and informational messages, and the right escalation depends on tmux version and requested format; the wrappers default to warning so callers can decide. To escalate to an exception, wrap the call in :func:warnings.catch_warnings with filterwarnings("error"):

import warnings

with warnings.catch_warnings():
    warnings.filterwarnings("error", category=UserWarning)
    result = pane.display_message("#{pane_id}", get_text=True)

libtmux 0.50.0: Unified Options and Hooks API (#516)¶

New unified options API¶

All tmux objects (Server, Session, Window, Pane) now share a consistent options interface through OptionsMixin:

# Get all options
session.show_options()

# Get a single option
session.show_option('base-index')

# Set an option
window.set_option('automatic-rename', True)

# Unset an option
window.unset_option('automatic-rename')

New hooks API¶

All tmux objects now support hook management through HooksMixin:

# Set a hook
session.set_hook('session-renamed', 'display-message "Renamed!"')

# Get hook value
session.show_hook('session-renamed')

# Get all hooks
session.show_hooks()

# Remove a hook
session.unset_hook('session-renamed')

Deprecated Window methods¶

The following Window methods are deprecated and will be removed in a future release:

Deprecated

Replacement

Window.set_window_option()

Window.set_option()

Window.show_window_option()

Window.show_option()

Window.show_window_options()

Window.show_options()

Before (deprecated):

window.set_window_option('automatic-rename', 'on')
window.show_window_option('automatic-rename')
window.show_window_options()

After (0.50.0+):

window.set_option('automatic-rename', True)
window.show_option('automatic-rename')
window.show_options()

Deprecated g parameter¶

The g parameter for global options is deprecated in favor of global_:

Before (deprecated):

session.show_option('status', g=True)
session.set_option('status', 'off', g=True)

After (0.50.0+):

session.show_option('status', global_=True)
session.set_option('status', 'off', global_=True)

Using the old g parameter will emit a DeprecationWarning.

libtmux 0.46.0 (2025-02-25)¶

Imports removed from libtmux.test (#580)¶

Root-level of imports from libtmux.test are no longer possible.

# Before 0.46.0
from libtmux.test import namer
# From 0.46.0 onward
from libtmux.test.named import namer

Same thing with constants:

# Before 0.46.0
from libtmux.test import (
  RETRY_INTERVAL_SECONDS,
  RETRY_TIMEOUT_SECONDS,
  TEST_SESSION_PREFIX
)
# From 0.46.0 onward
from libtmux.test.constants import (
  RETRY_INTERVAL_SECONDS,
  RETRY_TIMEOUT_SECONDS,
  TEST_SESSION_PREFIX
)

libtmux 0.45.0 (2025-02-23)¶

Test helpers: Module moves¶

Test helper functionality has been split into focused modules (#578):

  • libtmux.test module split into:

    • libtmux.test.constants: Test-related constants (TEST_SESSION_PREFIX, etc.)

    • libtmux.test.environment: Environment variable mocking

    • libtmux.test.random: Random string generation utilities

    • libtmux.test.temporary: Temporary session/window management

Breaking: Import paths have changed. Update imports:

# Old (0.44.x and earlier)
from libtmux.test import (
    TEST_SESSION_PREFIX,
    get_test_session_name,
    get_test_window_name,
    namer,
    temp_session,
    temp_window,
    EnvironmentVarGuard,
)
# New (0.45.0+)
from libtmux.test.constants import TEST_SESSION_PREFIX
from libtmux.test.environment import EnvironmentVarGuard
from libtmux.test.random import get_test_session_name, get_test_window_name, namer
from libtmux.test.temporary import temp_session, temp_window

0.35.0: Commands require explicit targets (2024-03-17)¶

Commands require explicit targets (#535)¶

  • Server.cmd(), Session.cmd(), Window.cmd(), Pane.cmd() require passing target instead of ['-t', target], ['-tTargetName'], etc. This change is to avoid issues mistakenly interpreting -t in other shell values as targets.

    Before:

    session.cmd('send-keys', 'echo hello', '-t', '0')
    

    With 0.35.0 and after:

    session.cmd('send-keys', 'echo hello', target='0')
    

0.33.0: Deprecations for splitting (2024-03-03)¶

Deprecations (#532)¶

0.31.0: Renaming and command cleanup (2024-02-17)¶

Cleanups (#527)¶

Renamings (#527)¶

0.28.0: Resizing and detached by default (2024-02-15)¶

Detach by default¶

  • Session.new_window() + Window.split_window() no longer attaches by default (#523)

    • 0.28.0 and greater: Defaults to attach=False.

    • 0.27.1 and below: Defaults to attach=True.

    For the old behavior in 0.28.0 and beyond, pass attach=True explicitly.

Resizing panes¶

  • Pane.resize_pane() renamed to Pane.resize() (via #523)

    This convention will be more consistent with Window.resize().

  • Pane.resize_pane()’s params changed (#523)

    • No longer accepts -U, -D, -L, -R directly, instead accepts ResizeAdjustmentDirection (see below).

      • 0.27.1 and below: pane.resize_pane("-D", 20), pane.resize_pane("-R", 20)

      • 0.28.0 and beyond:

        from libtmux.constants import ResizeAdjustmentDirection
        pane.resize_pane(adjustment_direction=ResizeAdjustmentDirection.Down, adjustment=25)
        pane.resize_pane(
          adjustment_direction=ResizeAdjustmentDirection.Right, adjustment=25
        )
        

0.17.0: Simplified attributes (2022-12-26)¶

Finding objects / relations¶

Accessing attributes¶

  • 0.16 and below: window['id']

    0.17 and after: window.id

  • 0.16 and below: window.get('id')

    0.17 and after: window.id

  • 0.16 and below: window.get('id', None)

    0.17 and after: getattr(window, 'id', None)