Skip to content

Fix Tailscale validator resilience across CLI/path edge cases#466

Open
Crabbotix wants to merge 1 commit intoDimillian:mainfrom
artuskg:codex/tailscale-validator-hardening
Open

Fix Tailscale validator resilience across CLI/path edge cases#466
Crabbotix wants to merge 1 commit intoDimillian:mainfrom
artuskg:codex/tailscale-validator-hardening

Conversation

@Crabbotix
Copy link

What

  • Harden Tailscale status detection in the desktop backend so Settings -> Server -> Detect Tailscale is resilient to real-world CLI output and execution quirks.
  • Improve binary discovery and macOS execution fallback behavior.
  • Prevent error-path crashes from unsafe UTF-8 truncation.
  • Add regression tests for noisy JSON parsing and preview safety.

Why

We observed false validator failures even when Tailscale was installed and connected.
In local validation we confirmed a key environment contributor: the Tailscale GUI was installed and running, but the CLI was not discoverable via a normal tailscale command path. That can cause status probing to fail despite healthy Tailnet connectivity.

This PR keeps behavior robust even when environments differ:

  • PATH / install-layout variance across macOS/Linux
  • CLI output with extra prefix/suffix diagnostics
  • command execution differences between launch contexts

How

Backend hardening

  • src-tauri/src/tailscale/mod.rs

    • Added tailscale_output(...) with macOS fallback from launchctl asuser to direct execution.
    • Expanded binary candidates (including additional standard install paths).
    • Changed several probe/parse edge failures from hard command errors into degraded TailscaleStatus responses (installed: true, running: false, informative message).
    • Replaced byte-slicing preview logic with UTF-safe truncation helper.
  • src-tauri/src/tailscale/core.rs

    • Added resilient parsing that can recover valid JSON status objects from noisy output.
    • Added candidate scoring so the parser prefers the most Tailscale-shaped JSON object when multiple objects appear.
    • Kept support for minimal valid payloads (e.g. backend-state-only cases).

Tests

  • Added regression tests for:
    • prefix/suffix noise around JSON
    • braces/noise in prefix text
    • false-positive JSON prefixes and wrong-type keys
    • backend-state-only payload acceptance
    • UTF-8-safe preview truncation behavior

Validation performed

  • cd src-tauri && cargo test tailscale::core::tests::status_from_json_
  • cd src-tauri && cargo test tailscale::tests::truncates_preview_without_utf8_boundary_panics
  • cd src-tauri && cargo check

Additionally, on local machine after fixing CLI exposure, tailscale version and tailscale status --json both returned healthy output with BackendState: Running.

@Crabbotix
Copy link
Author

Reviewer quick context (What / Why / How):

What:

  • Hardened Tailscale detection so the settings validator is resilient to noisy CLI output and platform/path differences.
  • Added tests for parser edge cases and UTF-safe error preview handling.

Why:

  • We hit false validator failures while Tailscale was actually connected.
  • Root cause in local repro included CLI discovery/path mismatch (GUI present and connected, but CLI invocation path was inconsistent).

How:

  • Backend: improved command execution fallback and binary candidate discovery in tailscale module.
  • Parser: select best valid status JSON from noisy output instead of failing on first parse issue.
  • Error handling: degrade to informative status instead of hard throw on common probe/parse edge failures.

Happy to split/trim further if maintainers prefer a narrower patch shape.

@Crabbotix
Copy link
Author

Crabbotix commented Feb 20, 2026

Cross-OS note (important): this app is multi-platform and this patch was reviewed with macOS/Linux/Windows paths in mind.

What is cross-platform-safe in this PR:

  • src-tauri/src/tailscale/core.rs parser hardening is OS-agnostic.
  • src-tauri/src/tailscale/mod.rs uses macOS-specific launchctl asuser only behind cfg(target_os = "macos"), with direct execution fallback.
  • Linux and Windows stay on direct command execution paths.
  • Binary candidate discovery includes Linux and Windows standard locations.

Known existing parity gap (not introduced by this PR):

  • Forced daemon kill fallback is Unix-only (listener PID lookup + signal kill). On Windows, forced-stop fallback is limited if RPC shutdown fails.

CI coverage note:

  • Repository CI workflow defines matrix jobs for macos-latest, ubuntu-latest, and windows-latest; once checks run, we should treat all 3 as required confidence signals for merge.

If maintainers want, I can follow with a focused Windows parity PR for the forced-stop fallback path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Comments