Skip to content

fix(cli): don't run the tart backend when tart isn't installed - #11

Open
benlavalley wants to merge 1 commit into
circlesac:mainfrom
benlavalley:fix/tart-not-found
Open

fix(cli): don't run the tart backend when tart isn't installed#11
benlavalley wants to merge 1 commit into
circlesac:mainfrom
benlavalley:fix/tart-not-found

Conversation

@benlavalley

@benlavalley benlavalley commented Jun 30, 2026

Copy link
Copy Markdown

User description

The macOS sandbox slot defaults to tart regardless of the Linux backend, so a Docker-only Mac still creates a Tart backend that the 30s reconcile loop polls, printing "tart: command not found" on startup and every 30s.

Only create the macOS/Tart backend when the tart CLI is on PATH, and capture stderr in tartExec so tart invocations never leak shell errors to the console.


CodeAnt-AI Description

Hide Tart errors when the CLI is missing and avoid creating an unusable macOS backend

What Changed

  • macOS sandboxes no longer start with Tart unless the tart CLI is installed
  • When Tart is missing, the app shows a warning and skips the macOS backend instead of repeatedly logging command-not-found errors
  • Tart commands now keep their error output out of the main console, so failed Tart checks do not leak shell messages

Impact

✅ Fewer startup errors on Macs without Tart
✅ Cleaner console output during sandbox checks
✅ No unusable macOS backend when Tart is not installed

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • Bug Fixes

    • Improved macOS backend setup so it only enables the Tart-backed sandbox when the required command is available.
    • If Tart isn’t installed, the app now skips the macOS backend and shows a warning instead of failing unexpectedly.
    • Command execution for Tart now handles output more reliably, reducing noise during backend checks.
  • Tests

    • Added coverage for macOS backend availability handling and Tart command execution behavior.

@codeant-ai

codeant-ai Bot commented Jun 30, 2026

Copy link
Copy Markdown

CodeAnt AI is reviewing your PR.

@codeant-ai

codeant-ai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@benlavalley, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 54 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a05315c9-851c-484c-8966-3e37d98acbc4

📥 Commits

Reviewing files that changed from the base of the PR and between 5efe0e1 and c12fa66.

📒 Files selected for processing (4)
  • cli/src/server/services/backend.ts
  • cli/src/server/services/tart.ts
  • cli/test/unit/server/services/backend.spec.ts
  • cli/test/unit/server/services/tart.spec.ts
📝 Walkthrough

Walkthrough

Adds a TartBackend.isAvailable() static method that probes tart --version, and uses it in createBackends to disable the macOS tart backend with a warning when unavailable. Also sets explicit stdio options on execSync calls in tartExec. Corresponding unit tests are added.

Changes

Tart Availability Gating

Layer / File(s) Summary
isAvailable() and stdio handling
cli/src/server/services/tart.ts
Adds a static isAvailable() method checking tart --version with a timeout, and explicit stdio configuration on execSync calls in tartExec.
createBackends availability gating
cli/src/server/services/backend.ts
createBackends checks TartBackend.isAvailable() before instantiating the macOS backend, falling back to undefined with a console.warn when unavailable.
Tests for gating and stdio behavior
cli/test/unit/server/services/backend.spec.ts, cli/test/unit/server/services/tart.spec.ts
Adds tests covering createBackends behavior with mocked isAvailable(), and verifies tart --version/tart list calls use expected stdio settings.

Sequence Diagram(s)

sequenceDiagram
  participant createBackends
  participant TartBackend
  participant Console

  createBackends->>TartBackend: isAvailable()
  TartBackend-->>createBackends: true/false
  alt unavailable
    createBackends->>Console: warn("tart CLI not found")
    createBackends->>createBackends: set macos to undefined
  end
  createBackends->>createBackends: build BackendMap with macos value
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~15 minutes

Poem

A rabbit checks if tart is near,
"tart --version" — loud and clear!
If silent, paws give a worried sniff,
"No CLI here," a console whiff.
Backends adapt, no crash, no fright,
Hop on, dear code, you're set just right. 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: disabling the Tart backend when the tart CLI is not installed.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codeant-ai codeant-ai Bot added the size:M This PR changes 30-99 lines, ignoring generated files label Jun 30, 2026
Comment on lines +72 to +78
if (macos === "tart" && !TartBackend.isAvailable()) {
console.warn(
"macOS sandbox backend disabled: the 'tart' CLI was not found on PATH. " +
"Install tart (https://tart.run) to run macOS sandboxes.",
);
macos = undefined;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: This change silently unsets the configured macOS backend when Tart is unavailable, which introduces a new runtime path where macOS sandbox requests throw UnsupportedError from backendFor and bubble as uncaught 500s in CreateSandbox (that route does not handle UnsupportedError). Return a controlled error path (for example by surfacing an explicit startup/config error or ensuring request handlers map this case to a non-500 response) instead of silently dropping the backend. [api mismatch]

Severity Level: Major ⚠️
- ❌ POST /sandboxes macOS requests return 500 when backend missing.
- ⚠️ Async sandbox creation with macOS metadata also fails with 500.
- ⚠️ Misconfigured macOS backend silently ignored at startup.
Steps of Reproduction ✅
1. Start the server (createApp in cli/src/server/app.ts:30-41) on a host where
config.macosBackend resolves to "tart" (cli/src/server/config.ts:5) but the tart CLI is
not usable or not installed.

2. During startup, createApp calls createBackends (cli/src/server/app.ts:36-41), which
invokes createBackends in cli/src/server/services/backend.ts:65-85.

3. In createBackends, the new block at lines 70-78 detects macos === "tart" and
TartBackend.isAvailable() === false, logs the warning, and sets macos = undefined, so
backends.macos is omitted from the returned BackendMap.

4. A client sends POST /sandboxes with a JSON body whose metadata includes platform:
"macos" (metadata is accepted by CreateSandboxBodySchema in
cli/src/server/controllers/sandboxes/schemas.ts:8-13).

5. The request is handled by CreateSandbox.handle
(cli/src/server/controllers/sandboxes/index.ts:46-58), which calls
sandboxService.create(body) without any try/catch.

6. In SandboxService.create (cli/src/server/services/sandbox.ts:111-121),
resolvePlatform(req.metadata) returns "macos" when metadata.platform === "macos"
(resolvePlatform in cli/src/server/services/backend.ts:88-91), and backendFor("macos")
(cli/src/server/services/sandbox.ts:20-25) finds no macOS backend in this.backends and
throws UnsupportedError("No backend configured for platform \"macos\"").

7. CreateSandbox.handle does not handle UnsupportedError (compare with PauseSandbox and
ResumeSandbox in cli/src/server/controllers/sandboxes/index.ts:166-176 and 214-225, which
explicitly catch UnsupportedError), so the exception bubbles to Hono’s default error
handler and results in an HTTP 500 instead of a controlled 4xx/5xx response indicating
macOS is unsupported or misconfigured.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** cli/src/server/services/backend.ts
**Line:** 72:78
**Comment:**
	*Api Mismatch: This change silently unsets the configured macOS backend when Tart is unavailable, which introduces a new runtime path where macOS sandbox requests throw `UnsupportedError` from `backendFor` and bubble as uncaught 500s in `CreateSandbox` (that route does not handle `UnsupportedError`). Return a controlled error path (for example by surfacing an explicit startup/config error or ensuring request handlers map this case to a non-500 response) instead of silently dropping the backend.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

Comment on lines +96 to +103
static isAvailable(): boolean {
try {
execSync("tart --version", { stdio: "ignore", timeout: 5_000 });
return true;
} catch {
return false;
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: The availability probe treats every failure as “not installed” by catching all exceptions, so transient failures (timeout, permission, execution error) will incorrectly disable Tart and trigger misleading behavior. Restrict the false return to true “command not found” cases and surface/log other failures separately. [incorrect condition logic]

Severity Level: Major ⚠️
- ⚠️ Valid Tart installation misdetected as missing when command errors.
- ⚠️ macOS backend disabled despite Tart being installed and configured.
- ⚠️ Operators see misleading CLI-not-found warning message.
Steps of Reproduction ✅
1. Run the server on a macOS host where config.macosBackend resolves to "tart"
(cli/src/server/config.ts:5) and the tart binary exists on PATH but `tart --version` fails
(e.g., exits non-zero, times out >5s, or has a permission issue).

2. On startup, createApp (cli/src/server/app.ts:30-41) calls createBackends
(cli/src/server/services/backend.ts:65-85), passing macos: "tart".

3. Inside createBackends, the condition at cli/src/server/services/backend.ts:72 calls
TartBackend.isAvailable().

4. TartBackend.isAvailable (cli/src/server/services/tart.ts:96-103) runs execSync("tart
--version", { stdio: "ignore", timeout: 5_000 }); when `tart --version` fails for any
reason (non-zero exit, timeout, spawn error), execSync throws, the catch block at lines
100-102 catches all errors, and isAvailable() returns false.

5. Back in createBackends, because isAvailable() returned false, the code at
cli/src/server/services/backend.ts:72-78 logs "the 'tart' CLI was not found on PATH" and
sets macos = undefined, disabling the macOS backend even though the tart binary is present
but misbehaving.

6. Subsequent POST /sandboxes calls that include metadata.platform = "macos" are routed
through CreateSandbox.handle (cli/src/server/controllers/sandboxes/index.ts:46-58) and
SandboxService.create (cli/src/server/services/sandbox.ts:111-121); resolvePlatform
returns "macos", backendFor("macos") throws UnsupportedError because backends.macos is
missing (cli/src/server/services/sandbox.ts:20-24), and the error is not caught in
CreateSandbox, producing a 500 along with a misleading startup log claiming the CLI was
not found.

Fix in Cursor Fix in VSCode Claude

(Use Cmd/Ctrl + Click for best experience)

Prompt for AI Agent 🤖
This is a comment left during a code review.

**Path:** cli/src/server/services/tart.ts
**Line:** 96:103
**Comment:**
	*Incorrect Condition Logic: The availability probe treats every failure as “not installed” by catching all exceptions, so transient failures (timeout, permission, execution error) will incorrectly disable Tart and trigger misleading behavior. Restrict the false return to true “command not found” cases and surface/log other failures separately.

Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix
👍 | 👎

@codeant-ai

codeant-ai Bot commented Jun 30, 2026

Copy link
Copy Markdown

CodeAnt AI finished reviewing your PR.

The macOS sandbox slot defaults to tart regardless of the Linux backend, so
a Docker-only Mac still creates a Tart backend that the 30s reconcile loop
polls, printing "tart: command not found" on startup and every 30s.

Only create the macOS/Tart backend when the tart CLI is on PATH, and capture
stderr in tartExec so tart invocations never leak shell errors to the console.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants