vercel/ai · error · Error

${errorMessage} (exit ${result.exitCode})${result.stderr ? `

Error message

${errorMessage} (exit ${result.exitCode})${result.stderr ? `: ${result.stderr}` : ''}

What it means

Generic sandbox command failure thrown by runSandboxCommand in packages/harness/src/utils/write-skills.ts. It wraps any non-zero exit from a sandbox shell command used by writeSkills (creating the skills directory, writing the manifest, removing skill directories) with the caller-supplied errorMessage and the command's exit code and stderr. It indicates the filesystem mutation the harness attempted inside the sandbox did not succeed.

Source

Thrown at packages/harness/src/utils/write-skills.ts:448

      });
    }
  }
}

async function runSandboxCommand({
  sandbox,
  command,
  abortSignal,
  errorMessage,
}: {
  sandbox: Experimental_SandboxSession;
  command: string;
  abortSignal?: AbortSignal;
  errorMessage: string;
}): Promise<void> {
  const result = await sandbox.run({ command, abortSignal });
  if (result.exitCode !== 0) {
    throw new Error(
      `${errorMessage} (exit ${result.exitCode})${result.stderr ? `: ${result.stderr}` : ''}`,
    );
  }
}

function assertUniqueSkillNames(skills: ReadonlyArray<ProjectedSkill>): void {
  for (let index = 1; index < skills.length; index++) {
    if (skills[index - 1]!.name === skills[index]!.name) {
      throw new Error(`Duplicate skill name: ${skills[index]!.name}`);
    }
  }
}

function isSafeManifestSkillName(name: string): boolean {
  SAFE_MANIFEST_SKILL_NAME.lastIndex = 0;
  const matches = SAFE_MANIFEST_SKILL_NAME.test(name);
  SAFE_MANIFEST_SKILL_NAME.lastIndex = 0;
  return matches && name !== '.' && name !== '..' && !name.includes('/');

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Read the stderr in the error message to identify the failing command's cause (permissions, disk space, missing path).
  2. Ensure rootDir is writable by the sandbox user (chown/chmod or pick a writable directory).
  3. Free sandbox disk space / raise quota if writes fail.
  4. Re-run writeSkills after fixing — the pending-manifest recovery logic cleans partially written skills.

Example fix

// before
await writeSkills({ sandbox, rootDir: '/usr/share/skills', skills }); // read-only -> exit 1: Permission denied
// after
await writeSkills({ sandbox, rootDir: '/workspace/.skills', skills });
Defensive patterns

Strategy: retry

Validate before calling

// Ensure the target directory is writable before writing skills
await sandbox.run({ command: `mkdir -p ${rootDir} && test -w ${rootDir}` });

Try / catch

try {
  await writeSkills({ sandbox, rootDir, skills });
} catch (error) {
  if (/\(exit \d+\)/.test((error as Error).message)) {
    // stderr is appended to the message — log it, fix rootDir permissions/space, then retry once
    await fixSandboxFs(sandbox, rootDir);
    await writeSkills({ sandbox, rootDir, skills });
  } else throw error;
}

Prevention

When it happens

Trigger: Calling writeSkills when an underlying sandbox command fails: mkdir of rootDir fails (permissions, read-only fs), manifest write fails (disk full, quota), or rm of skill directories fails (permission denied, path is a mount point).

Common situations: RootDir not writable by the sandbox user; sandbox filesystem read-only or out of space; EBUSY/EPERM on removal of mounted directories; sandbox session dying mid-operation.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/93a7e78069e5284a. Report an issue: GitHub.