paperclipai/paperclip · error
A sandbox command is required.
Error message
A sandbox command is required.
What it means
commandScript builds the shell script sent to the CreateOS sandbox and requires a non-empty params.command. Without a command there is nothing to execute, so the plugin fails fast rather than sending an empty exec line to the remote host.
Solutions
- Set params.command to the program to run, e.g. { command: 'bash', args: ['-c', 'ls -la'] }.
- Ensure the command isn't an empty string — use a real executable name.
- Check the calling code path for a conditional that drops the command field.
Example fix
// before
exec({ args: ["-la"] })
// after
exec({ command: "ls", args: ["-la"] }) Defensive patterns
Strategy: validation
Validate before calling
if (typeof params.command !== 'string' || params.command.length === 0) throw new Error('params.command must be a non-empty string before execute()'); Type guard
function hasCommand(p) { return typeof p === 'object' && p !== null && typeof p.command === 'string' && p.command.length > 0; } Prevention
- Always pass command as the first, explicit field of execute params
- Type execute params so command is required (non-optional)
- Guard dynamic param construction with a required-fields check
When it happens
Trigger: Calling execute (or the script-building path) with PluginEnvironmentExecuteParams where command is undefined, null, or an empty string — even when args or stdin are supplied.
Common situations: Constructing execute params programmatically and forgetting to set command; spreading an options object where command was conditionally deleted; passing only args expecting the plugin to infer the program.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- : "sandboxTransport" must be one of .
- Sandbox duplex channel needs a plugin id, a provider key…
- sandbox runtime asset key collides with a reserved runtime…
- sandbox runtime asset key is not a simple path segment
- workspace_durable_seed_invalid
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18).
Data as JSON: /api/errors/07ceb8d5ccac7059.
Report an issue: GitHub.
Appendix: source
Thrown at packages/plugins/sandbox-providers/createos/src/execute.ts:18
import { randomUUID } from "node:crypto";
import { StringDecoder } from "node:string_decoder";
import { setTimeout as delay } from "node:timers/promises";
import type { PluginEnvironmentExecuteParams, PluginEnvironmentExecuteResult } from "@paperclipai/plugin-sdk";
import { CreateosApiError, CreateosClient, identifier, object } from "./client.js";
const MAX_LINE_BYTES = 1_048_576;
const MAX_CAPTURE_CHARS = 4_194_304;
export class CreateosCleanupError extends Error {}
export function shellQuote(value: string): string {
if (value.includes("\0")) throw new Error("Sandbox command values cannot contain NUL.");
return `'${value.replace(/'/g, `'"'"'`)}'`;
}
function commandScript(params: PluginEnvironmentExecuteParams, stdinPath: string | null): string {
if (!params.command) throw new Error("A sandbox command is required.");
const env = Object.entries(params.env ?? {}).map(([key, value]) => {
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key) || typeof value !== "string") {
throw new Error("Invalid sandbox environment variable.");
}
return `${key}=${shellQuote(value)}`;
});
const command = [params.command, ...(params.args ?? [])].map(shellQuote).join(" ");
return [
params.cwd ? `cd -- ${shellQuote(params.cwd)} || exit` : "",
`exec env ${env.join(" ")} ${command}${stdinPath ? ` < ${shellQuote(stdinPath)}` : ""}`,
].filter(Boolean).join("\n");
}
async function* events(response: Response): AsyncGenerator<Record<string, unknown>> {
if (!response.body) throw new Error("CreateOS returned an empty process stream.");
const reader = response.body.getReader();
const decoder = new TextDecoder();
let pending = "";View on GitHub (pinned to 3f1d897a7c)