{"record":{"id":"036eef6141afce25","repo":"vercel/ai","slug":"harnessagent-sandboxconfig-workdir-must-not-co","errorCode":null,"errorMessage":"'HarnessAgent: `sandboxConfig.workDir` must not contain NUL.'","messagePattern":"'HarnessAgent: `sandboxConfig\\.workDir` must not contain NUL\\.'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/harness/src/agent/internal/sandbox-bootstrap.ts","lineNumber":42,"sourceCode":"  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 === '.' ||\n    normalized === '..' ||\n    normalized.startsWith('../')\n  ) {","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/harness/src/agent/internal/sandbox-bootstrap.ts#L24-L60","documentation":"normalizeSandboxWorkDir validates the `sandboxConfig.workDir` string before it is used in sandbox shell commands. A NUL character ('\\0') in a path is illegal on POSIX systems and would truncate the path or corrupt command execution, so the library rejects it eagerly with a clear message rather than failing obscurely later inside the sandbox.","triggerScenarios":"Calling createAgent/prepareSandboxForHarness with sandboxConfig.workDir containing a '\\0' character, e.g. from binary-parsed config, template strings built from buffers, or accidentally split multi-byte data.","commonSituations":"Config loaded from a binary or partially-corrupt file; building a path with String.fromCharCode(0) or a buffer slice; copy-pasted hidden control characters.","solutions":["Inspect the workDir value (e.g. JSON.stringify it to reveal hidden chars) and remove the NUL character.","Sanitize input before passing it: workDir = workDir.replace(/\\0/g, '').","If the path comes from a buffer or external source, decode it explicitly with Buffer.from(x, 'utf8').toString() and validate it first."],"exampleFix":"// before\nconst workDir = rawBuffer.toString().split('\\u0000')[0] + '\\u0000rest';\n// after\nconst workDir = rawBuffer.toString('utf8').split('\\u0000')[0];","handlingStrategy":"validation","validationCode":"function isValidWorkDir(w) { return typeof w === 'string' && w.length > 0 && !w.includes('\\0'); }","typeGuard":"function isNulFreeString(v: unknown): v is string { return typeof v === 'string' && !v.includes('\\0'); }","tryCatchPattern":"try { await prepareSandboxForHarness({ sandboxConfig: { workDir }, harnesses }); } catch (e) { if (e.message.includes('must not contain NUL')) { /* sanitize and retry */ } else throw e; }","preventionTips":["Sanitize any path derived from buffers or external input with replace(/\\0/g, '')","Log paths with JSON.stringify to reveal hidden control characters","Validate config values at load time, before agent construction"],"tags":["validation","path","sandbox","configuration"],"backgroundTag":"invalid-path-character","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}