vercel/ai · error · Error

prepareSandboxForHarness: at least one harness must be provi

Error message

prepareSandboxForHarness: at least one harness must be provided.

What it means

prepareSandboxForHarness exists to pre-warm a sandbox for one or more harnesses; calling it with an empty harnesses array would be a no-op with misleading success semantics, so it throws. At least one harness entry is required.

Source

Thrown at packages/harness/src/agent/prepare-sandbox-for-harness.ts:53

 * committing, snapshotting, or otherwise persisting that modified filesystem.
 * When a later `HarnessAgent` session uses a sandbox created from the persisted
 * artifact, the adapter recomputes the same recipe identity and the existing
 * bootstrap marker makes the bootstrap logic a no-op.
 *
 * Repeated harness IDs are prepared once. When multiple adapters use the same
 * ID, the last adapter in `harnesses` is used.
 */
export async function prepareSandboxForHarness(options: {
  readonly session: SandboxSession;
  readonly harnesses: ReadonlyArray<HarnessAgentAdapter>;
  readonly sandboxConfig?: HarnessAgentSandboxConfig;
  readonly abortSignal?: AbortSignal;
}): Promise<PrepareSandboxForHarnessResult> {
  const sandboxConfig = options.sandboxConfig ?? {};
  validateSandboxBootstrapSettings(sandboxConfig);

  if (options.harnesses.length === 0) {
    throw new Error(
      'prepareSandboxForHarness: at least one harness must be provided.',
    );
  }

  const harnesses = [
    ...new Map(
      options.harnesses.map(harness => [harness.harnessId, harness]),
    ).values(),
  ].sort((a, b) => a.harnessId.localeCompare(b.harnessId));

  const workDir =
    sandboxConfig.workDir == null
      ? undefined
      : normalizeSandboxWorkDir(sandboxConfig.workDir);
  const recipeIdentities: Record<string, string> = {};
  const skippedHarnessIds: string[] = [];
  let defaultWorkingDirectory: string | undefined;

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Pass at least one harness in the harnesses array.
  2. Guard the call: only invoke prepareSandboxForHarness when harnesses.length > 0.
  3. Fix the logic that builds the harnesses list so it isn't empty.

Example fix

// before
await prepareSandboxForHarness({ harnesses: [], sandboxConfig });
// after
if (harnesses.length > 0) {
  await prepareSandboxForHarness({ harnesses, sandboxConfig });
}
Defensive patterns

Strategy: validation

Validate before calling

if (!harnesses || harnesses.length === 0) return; // or throw early with context

Try / catch

try { await prepareSandboxForHarness({ harnesses, sandboxConfig }); } catch (e) { if (e.message.includes('at least one harness')) { /* skip pre-warm or build harnesses */ } else throw e; }

Prevention

When it happens

Trigger: Calling prepareSandboxForHarness({ harnesses: [] }) — e.g. when the harness list is built conditionally and every condition was false.

Common situations: Dynamically collecting harnesses from feature flags that are all disabled; filtering the harness array before the call and accidentally emptying it.

Related errors


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