{"record":{"id":"36be6898b8382082","repo":"dbt-labs/dbt-core","slug":"failed-to-write-to","errorCode":null,"errorMessage":"Failed to write to {}: {}","messagePattern":"Failed to write to (.+?): (.+?)","errorType":"exception","errorClass":"minijinja::Error (InvalidOperation)","httpStatus":null,"severity":"error","filePath":"crates/dbt-jinja-utils/src/phases/run/run_node_context.rs","lineNumber":781,"sourceCode":"    }\n\n    // A stale directory sitting where we now write a flat file fails with EISDIR.\n    if full_path.is_dir()\n        && let Err(e) = fs::remove_dir_all(full_path)\n    {\n        return Err(Error::new(\n            ErrorKind::InvalidOperation,\n            format!(\n                \"Failed to remove stale directory {}: {}\",\n                full_path.display(),\n                e\n            ),\n        ));\n    }\n\n    match fs::write(full_path, payload) {\n        Ok(_) => Ok(()),\n        Err(e) => Err(Error::new(\n            ErrorKind::InvalidOperation,\n            format!(\"Failed to write to {}: {}\", full_path.display(), e),\n        )),\n    }\n}\n\n/// Returns the function used for the submit_python_job context.\nfn submit_python_job_context_fn()\n-> impl Fn(&State, &[MinijinjaValue]) -> Result<MinijinjaValue, Error> + Copy {\n    |state: &State, args: &[MinijinjaValue]| {\n        // Parse arguments: submit_python_job(parsed_model, compiled_code)\n        if args.len() != 2 {\n            return Err(Error::new(\n                ErrorKind::InvalidOperation,\n                format!(\"submit_python_job expects 2 arguments, got {}\", args.len()),\n            ));\n        }\n        let parsed_model = &args[0];","sourceCodeStart":763,"sourceCodeEnd":799,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-jinja-utils/src/phases/run/run_node_context.rs#L763-L799","documentation":"This error is thrown by the `write_file` helper in the run-node context when `fs::write` fails to persist a rendered payload to disk at the resolved `full_path`. It wraps the underlying OS error so the developer sees both the target path and the I/O reason. The library throws it because writing the compiled/intermediate file is a required side effect of the node context phase and cannot be silently skipped.","triggerScenarios":"Calling `write_file` (directly or via `write_file_creates_nested_path`, `write_file_replaces_stale_flat_file_on_parent_chain`, `write_file_replaces_stale_directory_at_target`, or the `call` entry point) when the target path is not writable: parent directory does not exist and could not be created, a stale directory occupies the target path, the filesystem is read-only, or permissions are insufficient.","commonSituations":"Running dbt in a container with a read-only or full disk; a previous run left a directory where a file is expected; write permissions on target/ or logs/ directories were tightened; concurrent runs racing on the same artifact path.","solutions":["Inspect the wrapped OS error (`e`) in the message to identify the exact I/O cause (NotFound, PermissionDenied, AlreadyExists, etc.).","Ensure the parent directory of the target path exists and is writable; remove any directory sitting exactly at the target path.","Check free disk space and that the filesystem is mounted read-write.","Re-run with correct file permissions (chown/chmod) for the user executing dbt."],"exampleFix":"// before (stale directory blocks file write)\n// target/compiled.sql is a directory -> fs::write fails\n// after\n// rm -rf target/compiled.sql  (or let write_file_replaces_stale_directory_at_target remove it), then re-run\n","handlingStrategy":"try-catch","validationCode":"use std::path::Path;\nfn ensure_writable_target(path: &Path) -> Result<(), String> {\n    if let Some(parent) = path.parent() {\n        if !parent.exists() {\n            std::fs::create_dir_all(parent).map_err(|e| e.to_string())?;\n        }\n    }\n    if path.is_dir() {\n        return Err(format!(\"{} is a directory, not a file\", path.display()));\n    }\n    Ok(())\n}","typeGuard":null,"tryCatchPattern":"match write_file(full_path, payload) {\n    Err(e) if e.to_string().contains(\"Failed to write to\") => {\n        // inspect wrapped OS error, fix path/permissions, optionally retry\n        eprintln!(\"artifact write failed: {e}\");\n    }\n    Err(e) => return Err(e),\n    Ok(_) => {}\n}","preventionTips":["Always create parent directories before writing artifacts.","Clean stale target/ directories between runs.","Check disk space and mount flags in CI containers.","Run dbt as a user with write access to the project directory."],"tags":["filesystem","io","rust"],"backgroundTag":"file-write-failed","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}