# How to Debug Agent Channel Backend Failures in Agent-Reach When Upstream Tools Are Installed but Not Working

> Debug Agent-Reach backend failures when upstream tools fail. Run `python -m agent_reach.cli doctor` to diagnose missing, broken, or timeout issues. Inspect probe results or reinstall for quick fixes.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: how-to-guide
- Published: 2026-07-09

---

**To debug agent channel backend failures in Agent-Reach, run `python -m agent_reach.cli doctor` to identify whether the backend is missing, broken, or timing out, then inspect `probe_command` results or reinstall the tool using the hint provided.**

Agent-Reach routes every request through specialized *channels* that verify upstream command-line tools (backends) are both present and executable before processing. When you encounter agent channel backend failures despite having the tool installed, the issue typically stems from stale virtual environment shims, permission errors, or path inconsistencies that standard installation checks miss. Understanding how the `probe_command` utility in [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py) distinguishes these failure modes allows you to resolve issues that simple `$PATH` checks cannot detect.

## Understanding How Agent-Reach Detects Backend Failures

Each channel implements a `check()` method that validates its required upstream tool before processing requests. This method relies on **`agent_reach.probe.probe_command`** to run a lightweight test command (typically `--version`) and categorize the result into one of five distinct statuses.

Unlike `shutil.which`, which only verifies file existence, the probe distinguishes three critical failure modes that look identical to basic checks:

| Probe status | Meaning |
|--------------|---------|
| **missing**  | Command not found on `$PATH`. |
| **broken**   | Command exists on `$PATH` but the executable cannot start (common with stale venv shims after Python upgrades). |
| **timeout**  | Command hangs or exceeds the execution time limit. |
| **error**    | Command runs but returns a non-zero exit code. |
| **ok**       | Command executes successfully and returns output. |

These statuses propagate through the channel's `check()` method in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py), which translates them into channel states: `"off"` (missing), `"error"` (broken/timeout), or `"warn"` (optional features missing).

## Running the Doctor Diagnostic Command

The fastest way to identify agent channel backend failures is using the built-in diagnostic tool. The **doctor** command aggregates all channel checks into a formatted Rich table via `agent_reach.doctor.check_all` and `format_report`.

```bash
python -m agent_reach.cli doctor

```

The output displays each channel with visual indicators: ✅ (ok), ⚠️ (warn), or ❌ (off/error). Crucially, it reveals the *active backend* when one is selected and provides specific remediation hints.

A **missing** backend appears as:

```text
[red][X][/red]  YouTube (yt-dlp 未安装。安装：pip install yt-dlp)

```

A **broken** installation (the tool is on `$PATH` but won't execute) appears as:

```text
[red][X][/red]  YouTube (yt-dlp 已安装但无法执行…)

```

## Inspecting Backend Health Programmatically

When the doctor indicates a failure, inspect the probe result directly using Python to determine the exact failure mode. Import `probe_command` from `agent_reach/probe` to test any backend binary:

```python
from agent_reach.probe import probe_command

p = probe_command("yt-dlp", ["--version"], package="yt-dlp")
print(p.status, p.output, p.hint)

```

The `status` attribute returns one of `missing`, `broken`, `timeout`, `error`, or `ok`. When `status` is `"broken"`, the `hint` attribute contains a ready-made remediation message, typically suggesting commands like `uv tool install --force yt-dlp` or `pipx reinstall yt-dlp` to fix stale interpreter references.

## Analyzing Channel Check Implementations

To understand exactly how a specific channel processes backend failures, examine its `check()` implementation. Most channels inherit from the base class defined in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py) and follow a standard pattern: they call `probe_command`, set `self.active_backend` on success, and return a tuple indicating status and message.

The YouTube channel in [`agent_reach/channels/youtube.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/youtube.py) demonstrates this pattern clearly. Its `check()` method probes the backend and maps each probe status to a specific return value:

- **missing** → `("off", "未安装...")`
- **broken** → `("error", "已安装但无法执行...")`
- **timeout/error** → `("error", ...)` or `("warn", ...)` depending on severity

Additionally, the YouTube channel validates JavaScript runtimes (`node` or `deno`) through the same probing mechanism, generating warnings if processing JavaScript-heavy sites without a runtime available.

## Resolving Specific Backend Failure Types

### Fixing Missing Backends

When `probe_command` returns `status="missing"`, install the required tool using your preferred package manager:

```bash
pip install yt-dlp

# or

npm install -g deno

# or

brew install node

```

### Repairing Broken Installations

A `status="broken"` result indicates the executable exists but cannot start, typically because the shebang points to a deleted Python interpreter (common after system Python upgrades). Follow the hint provided by the probe:

```text
命令存在但无法执行——通常是系统 Python 升级后 venv 解释器丢失。重装即可修复：
  uv tool install --force yt-dlp
或：pipx reinstall yt-dlp

```

### Handling Timeouts and Execution Errors

For `timeout` or `error` statuses, run the command manually to observe the failure:

```bash
yt-dlp --version

```

Check for missing dependencies, permission denials, or environment variable issues like `LD_LIBRARY_PATH` or locale settings that prevent execution.

### Forcing a Specific Backend

If a channel supports multiple backends, override the default order using the config key `<channel>_backend` or the environment variable `<CHANNEL>_BACKEND`. The `Channel.ordered_backends()` method in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py) processes this override, moving your specified backend to the front of the probe queue:

```bash
export YOUTUBE_BACKEND=yt-dlp
python -m agent_reach.cli doctor

```

Or set in `~/.agent-reach/config.yaml`:

```yaml
youtube_backend: yt-dlp

```

### Validating JavaScript Runtimes for YouTube

The YouTube channel specifically requires a JavaScript runtime for certain operations. If the doctor reports warnings about JS execution, install Node.js or Deno:

```bash
brew install node  # macOS

# or

npm install -g deno

```

After installation, rerun the doctor to confirm the warning clears.

## Summary

- **Agent-Reach** uses `probe_command` in [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py) to distinguish between missing, broken, timeout, and error states—far more granular than simple `$PATH` checks.
- Run **`python -m agent_reach.cli doctor`** to view all channel statuses and identify whether backends are missing, broken, or timing out.
- Inspect specific failures programmatically by importing `probe_command` and checking the `status` and `hint` attributes.
- For broken installations (command exists but won't run), reinstall using `uv tool install --force` or `pipx reinstall` to fix stale interpreter paths.
- Override backend selection per-channel using `<CHANNEL>_BACKEND` environment variables or config keys processed by `ordered_backends()` in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py).
- YouTube channel failures often require installing a JavaScript runtime (`node` or `deno`) in addition to the primary backend tool.

## Frequently Asked Questions

### What is the difference between "missing" and "broken" backend statuses in Agent-Reach?

**Missing** means the command is not found on `$PATH`—the tool is not installed or not in your shell's search path. **Broken** means the command exists on `$PATH` but the operating system cannot execute it, usually due to a stale virtual environment shim pointing to a deleted Python interpreter. The `probe_command` function in [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py) catches this distinction by attempting to launch the process, whereas `shutil.which` would incorrectly report it as present.

### How can I programmatically check which backend a channel is currently using?

Instantiate the channel and call its `check()` method with a Config object, then inspect the `active_backend` attribute:

```python
from agent_reach.channels.youtube import YouTubeChannel
from agent_reach.config import Config

yt = YouTubeChannel()
yt.check(Config())
print(yt.active_backend)  # e.g., "yt-dlp" or None

```

This mirrors the logic used by the doctor command in [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) when formatting its report.

### Can I force a channel to use a specific backend even if others are installed?

Yes. Set the environment variable `<CHANNEL>_BACKEND` (e.g., `YOUTUBE_BACKEND=yt-dlp`) or add a `<channel>_backend` key to your `~/.agent-reach/config.yaml`. The `ordered_backends()` method in [`agent_reach/channels/base.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/base.py) reads this configuration and moves your specified backend to the front of the probe list, ensuring it is checked first and selected if healthy.

### Why does the YouTube channel report backend failures when yt-dlp is definitely installed?

The YouTube channel in [`agent_reach/channels/youtube.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/youtube.py) performs additional validation beyond the basic backend check—it verifies that a JavaScript runtime (`node` or `deno`) is available for processing JavaScript-heavy sites. If yt-dlp is installed but the channel shows warnings or errors, run `python -m agent_reach.cli doctor` to see if it is requesting a JS runtime installation, or if the yt-dlp installation is actually broken (stale shim) rather than merely missing.