n8n-io/n8n · error

Failed to write file

Error message

Failed to write file ${filePath}: ${result.stderr}

What it means

writeFileViaSandbox ran its base64-encoded write command in the sandbox and the command completed with a non-zero exit or error output; the message includes the command's stderr so the shell-level failure (disk full, permission, path issue) is visible.

Solutions

  1. Inspect the embedded stderr to identify the shell failure (permissions, disk space, invalid path)
  2. Retry after fixing the environment; transient sandbox I/O is already retried by the wrapper
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at packages/@n8n/instance-ai/src/workspace/sandbox-fs.ts:153 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/d2420eda04311aac. Report an issue: GitHub.

Appendix: source

Thrown at packages/@n8n/instance-ai/src/workspace/sandbox-fs.ts:153

 * Write a file in the sandbox via shell command.
 * Uses base64 encoding to safely transfer arbitrary content without
 * shell escaping issues (heredocs break on certain characters).
 * Creates parent directories automatically.
 */
export async function writeFileViaSandbox(
	workspace: SandboxCommandTarget,
	filePath: string,
	content: string | Buffer,
	options?: SandboxIoRetryOptions,
): Promise<void> {
	await retryTransientSandboxIo(
		async () => {
			const runWriteCommand = async (command: string) => {
				const result = await runInSandbox(workspace, command, {
					abortSignal: options?.abortSignal,
				});
				if (result.exitCode !== 0) {
					throw new Error(`Failed to write file ${filePath}: ${result.stderr}`);
				}
			};

			// Ensure parent directory exists
			const dir = filePath.substring(0, filePath.lastIndexOf('/'));
			if (dir) {
				await runWriteCommand(`mkdir -p '${escapeSingleQuotes(dir)}'`);
			}

			// Encode content as base64, transfer it in small chunks, then decode in the sandbox.
			// Some providers run commands through spawn(), where a single huge argument can hit E2BIG.
			const b64 =
				typeof content === 'string'
					? Buffer.from(content, 'utf-8').toString('base64')
					: content.toString('base64');
			const tempPath = `${filePath}.base64.tmp-${Date.now()}-${Math.random().toString(36).slice(2)}`;
			const escapedTempPath = escapeSingleQuotes(tempPath);

View on GitHub (pinned to 5ac6606e81)