vercel/ai · error
'HarnessAgent: `sandboxConfig.workDir` must not contain NUL.
Error message
'HarnessAgent: `sandboxConfig.workDir` must not contain NUL.'
What it means
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.
Source
Thrown at packages/harness/src/agent/internal/sandbox-bootstrap.ts:42
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.',
);
}
if (workDir.includes('\\')) {
throw new Error(
'HarnessAgent: `sandboxConfig.workDir` must use POSIX path separators.',
);
}
if (posix.isAbsolute(workDir)) {
throw new Error('HarnessAgent: `sandboxConfig.workDir` must be relative.');
}
const normalized = posix.normalize(workDir);
if (
normalized === '.' ||
normalized === '..' ||
normalized.startsWith('../')
) {View on GitHub (pinned to 69428b1f8b)
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.
Example fix
// before
const workDir = rawBuffer.toString().split('\u0000')[0] + '\u0000rest';
// after
const workDir = rawBuffer.toString('utf8').split('\u0000')[0]; Defensive patterns
Strategy: validation
Validate before calling
function isValidWorkDir(w) { return typeof w === 'string' && w.length > 0 && !w.includes('\0'); } Type guard
function isNulFreeString(v: unknown): v is string { return typeof v === 'string' && !v.includes('\0'); } Try / catch
try { await prepareSandboxForHarness({ sandboxConfig: { workDir }, harnesses }); } catch (e) { if (e.message.includes('must not contain NUL')) { /* sanitize and retry */ } else throw e; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- 'HarnessAgent: `sandboxConfig.workDir` must be relative.'
- The Claude Code harness requires an explicit `portEndpoint`
- 'HarnessAgent: `sandboxConfig.workDir` must stay inside the
- prepareSandboxForHarness: at least one harness must be provi
- Failed to resolve sandbox default working directory: expecte
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/036eef6141afce25.
Report an issue: GitHub.