{"record":{"id":"c31b4f1ce7710bcd","repo":"dbt-labs/dbt-core","slug":"macros-and-sources-cannot-be-written-to-disk","errorCode":null,"errorMessage":"Macros and sources cannot be written to disk","messagePattern":"Macros and sources cannot be written to disk","errorType":"exception","errorClass":"minijinja::Error (InvalidOperation)","httpStatus":null,"severity":"error","filePath":"crates/dbt-jinja-utils/src/phases/run/run_node_context.rs","lineNumber":727,"sourceCode":"            Ok(_) => {}\n            Err(e) => {\n                return Err(Error::new(\n                    ErrorKind::InvalidOperation,\n                    format!(\"Failed to write file: {e}\"),\n                ));\n            }\n        }\n\n        // Return empty string on success\n        Ok(MinijinjaValue::from(\"\"))\n    }\n}\n\n/// Write a file to disk\nfn write_file(full_path: &Path, resource_type: &str, payload: &str) -> Result<(), Error> {\n    // Check if model is a Macro or SourceDefinition\n    if resource_type == \"macro\" || resource_type == \"source\" {\n        return Err(Error::new(\n            ErrorKind::InvalidOperation,\n            \"Macros and sources cannot be written to disk\",\n        ));\n    }\n\n    // Reconcile a target/ left behind by a different artifact layout — e.g.\n    // dbt Core v1, or a pre-#14125 Fusion that wrote snapshot run artifacts as\n    // a flat file where we now write a nested directory (or vice versa). Without\n    // this, a stale file sitting where we now need a directory fails the write\n    // below with ENOTDIR (\"Not a directory\"), and a stale directory sitting\n    // where we now write a flat file fails with EISDIR (\"Is a directory\").\n    // See https://github.com/dbt-labs/dbt-core/issues/15692.\n    if let Some(parent) = full_path.parent()\n        && !parent.is_dir()\n    {\n        // Parent is missing, or a stale file on the parent chain (from an older\n        // layout) sits where we now need a directory. Remove the deepest such\n        // file so create_dir_all can rebuild the tree, then create it.","sourceCodeStart":709,"sourceCodeEnd":745,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-jinja-utils/src/phases/run/run_node_context.rs#L709-L745","documentation":"write_file refuses to write artifacts for resource types 'macro' and 'source'. Macros and source definitions are not models with compiled artifacts, so writing them to the run artifacts directory is rejected up front rather than producing meaningless files.","triggerScenarios":"The write() context function is invoked from within a macro or a source node's rendering context (resource_type is 'macro' or 'source'), e.g. calling {{ write(payload) }} inside a macro body or during source rendering.","commonSituations":"Adding write() calls to shared macro helpers that also run for macros/sources; dispatch macros that render in macro context; accidental reuse of a run-node write pattern in source-parsing hooks.","solutions":["Remove the write() call from macro or source contexts; only call it in model/seed/snapshot node contexts.","Guard the call: {% if resource_type not in ['macro', 'source'] %}{{ write(payload) }}{% endif %}.","Move the write into a node-level hook or the model body instead of a shared macro."],"exampleFix":"-- before (inside a macro)\n{{ write(rendered_sql) }}\n-- after\n{% if resource_type not in ['macro', 'source'] %}{{ write(rendered_sql) }}{% endif %}","handlingStrategy":"validation","validationCode":"-- Jinja\n{% if resource_type not in ['macro', 'source'] %}\n  {{ write(payload) }}\n{% endif %}","typeGuard":null,"tryCatchPattern":"match write_file(&path, resource_type, payload) {\n    Err(e) if e.to_string().contains(\"Macros and sources cannot be written\") => {\n        // skip artifact write for macro/source contexts instead of failing\n    }\n    other => other?,\n}","preventionTips":["Only call write() from model/seed/snapshot node contexts, never from shared macros.","Gate write() calls on resource_type before invoking.","Review dispatch macros for side effects that run in macro context."],"tags":["unsupported-operation","jinja","artifacts","dbt"],"backgroundTag":"unsupported-operation","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"}