{"record":{"id":"b8b2f5ae0853f972","repo":"n8n-io/n8n","slug":"failed-to-write-label-tolowercase-filepath","errorCode":null,"errorMessage":"Failed to write ${label.toLowerCase()} \"${filePath}\": ${formatErrorForLog(error)}; command fallback failed: ${formatErrorForLog(fallbackError)}","messagePattern":"Failed to write (.+?) \"(.+?)\": (.+?); command fallback failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/@n8n/instance-ai/src/workspace/workspace-files.ts","lineNumber":150,"sourceCode":"\t\t\t\t\t}),\n\t\t\t\tfilePath,\n\t\t\t\toptions,\n\t\t\t);\n\t\t\treturn;\n\t\t} catch (error) {\n\t\t\tif (isAbortError(error)) throw error;\n\t\t\ttry {\n\t\t\t\tawait writeFileViaSandbox(workspace, filePath, content, options);\n\t\t\t\toptions?.logger.warn(`${label} filesystem write failed; used command fallback`, {\n\t\t\t\t\tpath: filePath,\n\t\t\t\t\terror: formatErrorForLog(error),\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t} catch (fallbackError) {\n\t\t\t\tif (isAbortError(fallbackError)) throw fallbackError;\n\t\t\t\t// Preserve whichever path carries quota metadata so callers can\n\t\t\t\t// classify the combined failure correctly.\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Failed to write ${label.toLowerCase()} \"${filePath}\": ${formatErrorForLog(error)}; command fallback failed: ${formatErrorForLog(fallbackError)}`,\n\t\t\t\t\t{ cause: selectWriteFailureCause(error, fallbackError) },\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\ttry {\n\t\tawait writeFileViaSandbox(workspace, filePath, content, options);\n\t} catch (error) {\n\t\tif (isAbortError(error)) throw error;\n\t\tthrow new Error(\n\t\t\t`Failed to write ${label.toLowerCase()} \"${filePath}\": ${formatErrorForLog(error)}`,\n\t\t\t{ cause: error },\n\t\t);\n\t}\n}\n","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/instance-ai/src/workspace/workspace-files.ts#L132-L168","documentation":"Thrown by writeWorkspaceFile when BOTH write paths fail: the primary workspace.filesystem.writeFile raised an error AND the sandbox command fallback (writeFileViaSandbox) also raised fallbackError. Neither was an abort error. The `cause` is chosen by selectWriteFailureCause, which prefers whichever of the two errors carries quota-exhausted metadata (errorCode === 'quota_exhausted') so callers can classify credit exhaustion correctly; otherwise the original write error wins.","triggerScenarios":"Calling writeWorkspaceFile where workspace.filesystem is defined (so the primary path runs) and both (a) filesystem.writeFile throws a non-abort error, and (b) writeFileViaSandbox throws a non-abort fallbackError inside the catch's try. Most common when the underlying resource (disk quota, Instance AI credit pool, or sandbox provider) is exhausted on both paths.","commonSituations":"Instance AI credit pool exhausted (quota_exhausted) — both the filesystem API and the command path report it; workspace disk full in Daytona so neither the API write nor the base64 command write can land; sandbox provider outage causing both the API and shell command to fail transiently at once.","solutions":["Inspect err.cause with isQuotaExhaustedError(cause) — if true, surface an Instance AI credits-exhausted message and stop retrying; writes will keep failing until credits refresh.","Check workspace disk usage with a sandbox command (df -h) if quota is not the cause.","Retry only if neither cause is quota_exhausted and the failure shape looks transient (status 5xx).","Verify the workspace is not paused/hibernated before writing."],"exampleFix":"// before\nawait writeWorkspaceFile(workspace, filePath, content, opts);\n\n// after — classify the combined failure\ntry {\n  await writeWorkspaceFile(workspace, filePath, content, opts);\n} catch (err) {\n  if (isQuotaExhaustedError(err.cause)) {\n    throw new Error('Instance AI credits exhausted — write blocked until credits refresh.');\n  }\n  throw err;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"import { isQuotaExhaustedError } from './utils/quota-error';\n\nfunction isQuotaWriteFailure(error: unknown): boolean {\n  return error instanceof Error && isQuotaExhaustedError(error.cause);\n}","tryCatchPattern":"try {\n  await writeWorkspaceFile(workspace, filePath, content, opts);\n} catch (err) {\n  if (isQuotaWriteFailure(err)) {\n    // surface credits-exhausted; do not retry\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always inspect err.cause with isQuotaExhaustedError before deciding to retry.","Do not retry quota-exhausted writes — they will keep failing until credits refresh.","Check workspace disk space before large multi-file writes via writeWorkspaceFileMap."],"tags":["sandbox","filesystem","write","quota","instance-ai","fallback"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}