{"record":{"id":"5b7dffd3644bcda4","repo":"vercel/ai","slug":"harnessagent-sandboxconfig-onbootstrap-and-sa","errorCode":null,"errorMessage":"'HarnessAgent: `sandboxConfig.onBootstrap` and `sandboxConfig.bootstrapHash` must be provided together.'","messagePattern":"'HarnessAgent: `sandboxConfig\\.onBootstrap` and `sandboxConfig\\.bootstrapHash` must be provided together\\.'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/harness/src/agent/internal/sandbox-bootstrap.ts","lineNumber":27,"sourceCode":"\ntype SandboxBootstrapSettings = Omit<HarnessAgentSandboxConfig, 'onSession'>;\n\nexport type SandboxBootstrapPlan = {\n  readonly recipe?: HarnessV1Bootstrap;\n  readonly recipeIdentity?: string;\n  readonly identity?: string;\n  readonly workDir?: string;\n  readonly onFirstCreate?: (\n    session: SandboxSession,\n    opts: { abortSignal?: AbortSignal },\n  ) => Promise<void>;\n};\n\nexport function validateSandboxBootstrapSettings(\n  settings: SandboxBootstrapSettings,\n): void {\n  if ((settings.onBootstrap == null) !== (settings.bootstrapHash == null)) {\n    throw new Error(\n      'HarnessAgent: `sandboxConfig.onBootstrap` and `sandboxConfig.bootstrapHash` must be provided together.',\n    );\n  }\n\n  if (settings.workDir != null) {\n    normalizeSandboxWorkDir(settings.workDir);\n  }\n}\n\nexport function normalizeSandboxWorkDir(workDir: string): string {\n  if (workDir.length === 0) {\n    throw new Error('HarnessAgent: `sandboxConfig.workDir` must not be empty.');\n  }\n  if (workDir.includes('\\0')) {\n    throw new Error(\n      'HarnessAgent: `sandboxConfig.workDir` must not contain NUL.',\n    );\n  }","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness/src/agent/internal/sandbox-bootstrap.ts#L9-L45","documentation":"`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.","triggerScenarios":"Constructing a HarnessAgent (directly or via `prepareHarnessSandboxTemplate`/`prepareSandboxForHarness`) with a `sandboxConfig` that sets `onBootstrap` but not `bootstrapHash`, or `bootstrapHash` but not `onBootstrap`.","commonSituations":"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.","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."],"exampleFix":"// before\nnew HarnessAgent({ sandboxConfig: { onBootstrap: async (sb) => { ... } } }); // missing hash\n\n// after\nnew HarnessAgent({\n  sandboxConfig: {\n    onBootstrap: async (sb) => { ... },\n    bootstrapHash: 'sha256:abc123...',\n  },\n});","handlingStrategy":"validation","validationCode":"const { onBootstrap, bootstrapHash } = sandboxConfig;\nif ((onBootstrap == null) !== (bootstrapHash == null)) {\n  throw new Error('sandboxConfig.onBootstrap and bootstrapHash must be provided together.');\n}","typeGuard":null,"tryCatchPattern":"try {\n  const agent = new HarnessAgent({ sandboxConfig });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('must be provided together')) {\n    // add the missing half of the bootstrap pair or remove both\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["config","sandbox","validation","harness"],"backgroundTag":"incomplete-configuration","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}