vercel/ai · error
'HarnessAgent: `sandboxConfig.onBootstrap` and `sandboxConfi
Error message
'HarnessAgent: `sandboxConfig.onBootstrap` and `sandboxConfig.bootstrapHash` must be provided together.'
What it means
`validateSandboxBootstrapSettings` enforces that `sandboxConfig.onBootstrap` (the bootstrap script/callback) and `sandboxConfig.bootstrapHash` (its expected hash for verification/caching) are supplied as a pair. Providing exactly one of them would leave the bootstrap either unverifiable or hash-less, so the constructor/validation throws immediately.
Source
Thrown at packages/harness/src/agent/internal/sandbox-bootstrap.ts:27
type SandboxBootstrapSettings = Omit<HarnessAgentSandboxConfig, 'onSession'>;
export type SandboxBootstrapPlan = {
readonly recipe?: HarnessV1Bootstrap;
readonly recipeIdentity?: string;
readonly identity?: string;
readonly workDir?: string;
readonly onFirstCreate?: (
session: SandboxSession,
opts: { abortSignal?: AbortSignal },
) => Promise<void>;
};
export function validateSandboxBootstrapSettings(
settings: SandboxBootstrapSettings,
): void {
if ((settings.onBootstrap == null) !== (settings.bootstrapHash == null)) {
throw new Error(
'HarnessAgent: `sandboxConfig.onBootstrap` and `sandboxConfig.bootstrapHash` must be provided together.',
);
}
if (settings.workDir != null) {
normalizeSandboxWorkDir(settings.workDir);
}
}
export function normalizeSandboxWorkDir(workDir: string): string {
if (workDir.length === 0) {
throw new Error('HarnessAgent: `sandboxConfig.workDir` must not be empty.');
}
if (workDir.includes('\0')) {
throw new Error(
'HarnessAgent: `sandboxConfig.workDir` must not contain NUL.',
);
}View on GitHub (pinned to 69428b1f8b)
Solutions
- Provide both `onBootstrap` and `bootstrapHash` together in `sandboxConfig`.
- If bootstrap is not needed, remove both fields entirely.
- If the hash is generated by a build step, verify that step succeeded and the hash value is defined before constructing the agent.
Example fix
// before
new HarnessAgent({ sandboxConfig: { onBootstrap: async (sb) => { ... } } }); // missing hash
// after
new HarnessAgent({
sandboxConfig: {
onBootstrap: async (sb) => { ... },
bootstrapHash: 'sha256:abc123...',
},
}); Defensive patterns
Strategy: validation
Validate before calling
const { onBootstrap, bootstrapHash } = sandboxConfig;
if ((onBootstrap == null) !== (bootstrapHash == null)) {
throw new Error('sandboxConfig.onBootstrap and bootstrapHash must be provided together.');
} Try / catch
try {
const agent = new HarnessAgent({ sandboxConfig });
} catch (e) {
if (e instanceof Error && e.message.includes('must be provided together')) {
// add the missing half of the bootstrap pair or remove both
}
throw e;
} Prevention
- Always set onBootstrap and bootstrapHash as a single config object literal.
- Verify build steps that compute bootstrapHash actually ran before constructing the agent.
- Use a typed config helper that requires both fields together.
When it happens
Trigger: Constructing a HarnessAgent (directly or via `prepareHarnessSandboxTemplate`/`prepareSandboxForHarness`) with a `sandboxConfig` that sets `onBootstrap` but not `bootstrapHash`, or `bootstrapHash` but not `onBootstrap`.
Common situations: Copying a config snippet and forgetting the hash line; computing the hash in a build step that failed silently so only one field was populated; toggling bootstrap on via env/feature flag without updating the paired field.
Related errors
- 'HarnessAgent: `sandboxConfig.workDir` must not be empty.'
- Failed to resolve sandbox default working directory: expecte
- Invalid AI SDK harness skills manifest: ${manifestPath}
- Invalid host tool catalog.
- The Claude Code harness requires an explicit `portEndpoint`
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/5b7dffd3644bcda4.
Report an issue: GitHub.