vercel-labs/agent-browser · error

Screenshot did not return a file path.

Error message

Screenshot did not return a file path.

What it means

This throw lives in the example code of the vercel-sandbox skill (skill-data/vercel-sandbox/SKILL.md:53), not in library code. After running `agent-browser screenshot` through runAgentBrowserCommand, the snippet reads ssResult.json?.data?.path and throws when no path string came back. A missing path means the command's stdout was not the expected JSON payload (parseJson in shared.ts returns null on bad JSON) or the JSON lacked data.path.

Solutions

  1. Log ssResult.stdout, ssResult.stderr, and ssResult.exitCode right before the throw to see what the CLI actually returned; that distinguishes bad JSON from a missing field.
  2. Remove any custom installSpec pin so the sandbox installs agent-browser at the version matching @agent-browser/sandbox (DEFAULT_AGENT_BROWSER_INSTALL_SPEC in shared.ts:38), or bump the pinned spec to a version that returns { data: { path } } from screenshot --json.
  3. Ensure the screenshot call keeps JSON mode on: call runAgentBrowserCommand(sandbox, ["screenshot"]) without { json: false }, which would make stdout non-JSON.
  4. Check that a page is actually open in the session (a prior `open` succeeded and throwIfCommandFailed did not fire) before taking the screenshot.

Example fix

// before
const ssResult = await runAgentBrowserCommand<{ data?: { path?: string } }>(sandbox, [
  "screenshot",
]);
const ssPath = ssResult.json?.data?.path;
if (!ssPath) throw new Error("Screenshot did not return a file path.");

// after
const ssResult = await runAgentBrowserCommand<{ data?: { path?: string } }>(sandbox, [
  "screenshot",
]);
const ssPath = ssResult.json?.data?.path;
if (!ssPath) {
  throw new Error(
    `Screenshot did not return a file path (exit=${ssResult.exitCode}): ${ssResult.stderr || ssResult.stdout}`,
  );
}
Defensive patterns

Strategy: type-guard

Validate before calling

const ssResult = await runAgentBrowserCommand<{ data?: { path?: string } }>(sandbox, [
  "screenshot",
]);

if (ssResult.exitCode !== 0) {
  throw new Error(`screenshot failed (exit ${ssResult.exitCode}): ${ssResult.stderr}`);
}
if (ssResult.json === null) {
  throw new Error(`screenshot stdout was not JSON: ${ssResult.stdout.slice(0, 200)}`);
}

Type guard

interface ScreenshotJson {
  readonly data?: { readonly path?: string };
}

function hasScreenshotPath(
  result: AgentBrowserCommandResult<ScreenshotJson>,
): result is AgentBrowserCommandResult<ScreenshotJson> & {
  readonly json: ScreenshotJson & { readonly data: { readonly path: string } };
} {
  return typeof result.json?.data?.path === "string" && result.json.data.path.length > 0;
}

const ssResult = await runAgentBrowserCommand<ScreenshotJson>(sandbox, ["screenshot"]);
if (!hasScreenshotPath(ssResult)) {
  throw new Error(
    `Screenshot did not return a file path (exit=${ssResult.exitCode}): ${ssResult.stderr || ssResult.stdout}`,
  );
}
const ssPath = ssResult.json.data.path; // narrowed to string

Try / catch

try {
  const b64 = await sandbox.runCommand("base64", ["-w", "0", ssPath]);
} catch (error) {
  if (error instanceof Error && error.message.includes("Screenshot did not return a file path")) {
    // inspect ssResult.stdout/stderr: usually version drift between helper and CLI
    throw new Error(
      `agent-browser CLI returned unexpected screenshot output. Upgrade the CLI install spec. Raw: ${ssResult.stdout.slice(0, 200)}`,
    );
  }
  throw error;
}

Prevention

When it happens

Trigger: The screenshot command runs with --json appended automatically (buildAgentBrowserArgv in shared.ts:82-84), so this triggers when the agent-browser CLI inside the sandbox prints non-JSON output (older CLI versions, warnings mixed into stdout), returns a JSON shape without data.path, or when json parsing yields null because stdout is empty (e.g. the command failed in a way that bypassed throwIfCommandFailed, or the CLI version installed via a custom installSpec predates the path-in-JSON behavior).

Common situations: Version drift: @agent-browser/sandbox helpers expect the JSON contract of the matching agent-browser CLI, but installSpec pins an older CLI; stdout polluted by shell warnings from the sandbox VM; a CLI that prints the raw path as plain text instead of JSON; invoking the snippet against a session where the screenshot silently failed.

Related errors


AI-assisted analysis of vercel-labs/agent-browser@548b159b30 (2026-08-16). Data as JSON: /api/errors/efac5247b248ce6b. Report an issue: GitHub.

Appendix: source

Thrown at skill-data/vercel-sandbox/SKILL.md:53

## Screenshot

The `screenshot --json` command saves to a file and returns the path. Read the file back as base64:

```ts
export async function screenshotUrl(url: string) {
  return withBrowser(async (sandbox) => {
    await runAgentBrowserCommand(sandbox, ["open", url]);

    const titleResult = await runAgentBrowserCommand<{ data?: { title?: string } }>(sandbox, [
      "get", "title",
    ]);
    const title = titleResult.json?.data?.title || url;

    const ssResult = await runAgentBrowserCommand<{ data?: { path?: string } }>(sandbox, [
      "screenshot",
    ]);
    const ssPath = ssResult.json?.data?.path;
    if (!ssPath) throw new Error("Screenshot did not return a file path.");
    const b64Result = await sandbox.runCommand("base64", ["-w", "0", ssPath]);
    const screenshot = (await b64Result.stdout()).trim();

    await runAgentBrowserCommand(sandbox, ["close"], { json: false });

    return { title, screenshot };
  });
}
```

## Accessibility Snapshot

```ts
export async function snapshotUrl(url: string) {
  return withBrowser(async (sandbox) => {
    await runAgentBrowserCommand(sandbox, ["open", url]);

    const titleResult = await runAgentBrowserCommand<{ data?: { title?: string } }>(sandbox, [

View on GitHub (pinned to 548b159b30)