iOfficeAI/OfficeCLI · error · OfficeCliError

127

127

Error message

officecli CLI not found: {bin!r} is not on PATH nor in the default install location (~/.local/bin, or %LOCALAPPDATA%\OfficeCLI on Windows). This SDK only forwards commands to the officecli binary, which must be installed separately. Install it:
    python -m officecli install            # runs the official installer
    # or: curl -fsSL https://d.officecli.ai/install.sh | bash
Already installed elsewhere? pass binary="/path/to/officecli".

What it means

Raised by the Python SDK (code 127) when the officecli binary cannot be found: subprocess.run raises FileNotFoundError because the binary is neither on PATH nor in the default install location (~/.local/bin on Unix, %LOCALAPPDATA%\OfficeCLI on Windows). The SDK only forwards commands to the separately-installed officecli binary, so it surfaces clear install guidance rather than a raw FileNotFoundError.

Source

Thrown at sdk/python/officecli.py:368

        for cand in filter(None, (shutil.which(binary), _install_dir_candidate(binary))):
            if _runs_ok(cand):
                return cand
    return binary                          # give up; _run_cli raises the helpful error


def _run_cli(binary, argv):
    """Run `binary <argv...>` (capturing output). A missing binary surfaces as a
    clear OfficeCliError with install guidance, not a raw FileNotFoundError."""
    try:
        # text=True alone decodes with locale.getencoding() — the ANSI code page
        # on Windows (cp936/cp1252). The CLI always writes UTF-8, so a message
        # carrying a non-ASCII path raised UnicodeDecodeError (or mojibake) out
        # of subprocess instead of a clean OfficeCliError. The resident-pipe
        # route below already decodes utf-8; keep the two agreeing.
        return subprocess.run([binary, *argv], capture_output=True,
                              text=True, encoding="utf-8", errors="replace")
    except FileNotFoundError:
        raise OfficeCliError(127, _MISSING_CLI.format(bin=binary)) from None


# ---------------------------------------------------------------- the shell
class Document:
    def __init__(self, path, binary="officecli", timeout=30.0):
        # Canonical (Windows 8.3-expanded) so the pipe name AND the _serves()
        # path comparison both match what the resident reports.
        self.path = _canonical_path(path)
        self.bin = _resolve_binary(binary)
        self.timeout = timeout          # connect timeout (s); the reply read blocks
        self._main, self._ping = pipe_paths(self.path)
        self._restart_lock = threading.Lock()   # serialize dead-resident restarts
        self._start()

    def _start(self):
        # If a resident is ALREADY serving this file, reuse it — no process spawn.
        # Mirrors officecli, where a command after `create` reuses the resident
        # `create` auto-started instead of re-running `open`. _serves() is a real

View on GitHub (pinned to 1ced45e900)

Solutions

  1. Install the binary: python -m officecli install (or the documented curl/PowerShell installer).
  2. If installed elsewhere, pass binary='/path/to/officecli' to open/create/Document.
  3. Ensure the install location is on PATH (export PATH="$HOME/.local/bin:$PATH").

Example fix

# before
doc = officecli.open('book.xlsx')   # binary missing
# after
officecli.install()                  # installs the officecli binary
doc = officecli.open('book.xlsx')
# or point at an existing binary
doc = officecli.Document('book.xlsx', binary='/opt/officecli/bin/officecli')
Defensive patterns

Strategy: fallback

Validate before calling

import shutil, officecli

def resolve_binary(explicit=None):
    if explicit and shutil.which(explicit):
        return explicit
    if shutil.which('officecli'):
        return 'officecli'
    raise officecli.OfficeCliError(127, 'officecli binary not found — run officecli.install()')

resolve_binary()  # call before opening a Document

Type guard

import shutil
def officecli_available(binary='officecli'):
    return shutil.which(binary) is not None

Try / catch

try:
    doc = officecli.open('book.xlsx')
except officecli.OfficeCliError as e:
    if e.code == 127:
        officecli.install()           # then retry open
        doc = officecli.open('book.xlsx')
    else:
        raise

Prevention

When it happens

Trigger: Using the SDK (officecli.open/create/Document) before installing the officecli binary; binary installed in a non-default location not on PATH; CI/container image missing the binary.

Common situations: Fresh environment without the CLI; a venv/PATH that excludes ~/.local/bin; a Docker image that installed the Python SDK but not the native binary.

Related errors


AI-assisted analysis of iOfficeAI/OfficeCLI@1ced45e900 (2026-08-13). Data as JSON: /api/errors/94d43c611742170c. Report an issue: GitHub.