{"record":{"id":"de742de709cda9ff","repo":"vercel/ai","slug":"harnessagent-sandboxconfig-workdir-must-not-be","errorCode":null,"errorMessage":"'HarnessAgent: `sandboxConfig.workDir` must not be empty.'","messagePattern":"'HarnessAgent: `sandboxConfig\\.workDir` must not be empty\\.'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/harness/src/agent/internal/sandbox-bootstrap.ts","lineNumber":39,"sourceCode":"};\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  }\n  if (workDir.includes('\\\\')) {\n    throw new Error(\n      'HarnessAgent: `sandboxConfig.workDir` must use POSIX path separators.',\n    );\n  }\n  if (posix.isAbsolute(workDir)) {\n    throw new Error('HarnessAgent: `sandboxConfig.workDir` must be relative.');\n  }\n\n  const normalized = posix.normalize(workDir);\n  if (\n    normalized === '.' ||","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness/src/agent/internal/sandbox-bootstrap.ts#L21-L57","documentation":"`normalizeSandboxWorkDir` rejects an empty `sandboxConfig.workDir` string. A work directory must be a non-empty path for the sandbox to know where to operate; an empty string is never a valid target, so validation fails fast with this error (an adjacent check also rejects NUL bytes).","triggerScenarios":"Passing `sandboxConfig.workDir: ''` (or a variable that resolves to an empty string) when constructing a HarnessAgent or calling code that normalizes the work dir (e.g. the `workDir` getter path).","commonSituations":"Reading workDir from an env var like `SANDBOX_WORK_DIR` that is unset/empty; template strings built from missing config; defaulting code that assigns '' instead of undefined.","solutions":["Set `sandboxConfig.workDir` to a non-empty absolute path (e.g. '/workspace').","If the value comes from an env var, default or validate it before constructing the agent (e.g. `process.env.SANDBOX_WORK_DIR ?? '/workspace'`).","Omit `workDir` entirely if it is optional and you have no value, rather than passing ''."],"exampleFix":"// before\nnew HarnessAgent({ sandboxConfig: { workDir: process.env.SANDBOX_WORK_DIR ?? '' } });\n\n// after\nconst workDir = process.env.SANDBOX_WORK_DIR;\nif (!workDir) throw new Error('SANDBOX_WORK_DIR is required');\nnew HarnessAgent({ sandboxConfig: { workDir } });","handlingStrategy":"validation","validationCode":"if (typeof workDir !== 'string' || workDir.length === 0) {\n  throw new Error('sandboxConfig.workDir must be a non-empty string.');\n}","typeGuard":"function isValidWorkDir(v: unknown): v is string {\n  return typeof v === 'string' && v.length > 0 && !v.includes('\\0');\n}","tryCatchPattern":"try {\n  const agent = new HarnessAgent({ sandboxConfig: { workDir } });\n} catch (e) {\n  if (e instanceof Error && e.message.includes('workDir')) {\n    // supply a valid non-empty path or omit workDir\n  }\n  throw e;\n}","preventionTips":["Validate env-var-backed config values before constructing the agent.","Prefer undefined over '' when a value is missing.","Fail fast at config-load time with a clear message naming the env var."],"tags":["config","sandbox","validation","workdir"],"backgroundTag":"invalid-config-value","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}