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.
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)
Solutions
- 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.
- 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.
- Ensure the screenshot call keeps JSON mode on: call runAgentBrowserCommand(sandbox, ["screenshot"]) without { json: false }, which would make stdout non-JSON.
- 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
- Keep the agent-browser CLI version inside the sandbox aligned with @agent-browser/sandbox: omit installSpec so DEFAULT_AGENT_BROWSER_INSTALL_SPEC applies.
- Always assert exitCode and json !== null on runAgentBrowserCommand results before reading nested fields.
- Never call screenshot with { json: false } when you need the path; the JSON payload is the contract for data.path.
- Wrap the screenshot step so failures include stdout/stderr context, making sandbox VM output problems diagnosable from logs.
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
- @vercel/sandbox did not export Sandbox.
- React DevTools hook not installed - relaunch with --enable r
- renders recording not active - run `react renders start` fir
- agent-browser ${args[0] ?? ""} failed: ${envelope.error ?? "
- agent-browser command failed: ${result.command}\n${detail}
AI-assisted analysis of vercel-labs/agent-browser@548b159b30 (2026-08-16).
Data as JSON: /api/errors/efac5247b248ce6b.
Report an issue: GitHub.