{"record":{"id":"33adcf1baae03aa1","repo":"dbt-labs/dbt-core","slug":"compiled-code-must-be-a-string","errorCode":null,"errorMessage":"compiled_code must be a string","messagePattern":"compiled_code must be a string","errorType":"validation","errorClass":"minijinja::Error (InvalidOperation)","httpStatus":null,"severity":"error","filePath":"crates/dbt-jinja-utils/src/phases/run/run_node_context.rs","lineNumber":801,"sourceCode":"            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];\n        let compiled_code = args[1].as_str().ok_or_else(|| {\n            Error::new(\n                ErrorKind::InvalidOperation,\n                \"compiled_code must be a string\",\n            )\n        })?;\n\n        // Note(Ani):\n        // dbt-core validates:\n        //   - macro_stack.depth == 2\n        //   - call_stack[1] == \"macro.dbt.statement\"\n        //   - \"materialization\" in call_stack[0]\n        //\n        // In fusion, we shouldn't need to do this because this funciton is only registered in the run node context\n        // so if a user tries to use it outside of a statement.sql macro, in a materialization macro, it will fail earlier due to an unrecongized function call.\n\n        // Get adapter from context and call submit_python_job\n        let adapter = state\n            .lookup(\"adapter\", &[])\n            .ok_or_else(|| Error::new(ErrorKind::UndefinedError, \"adapter not found in context\"))?;","sourceCodeStart":783,"sourceCodeEnd":819,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/dbt-jinja-utils/src/phases/run/run_node_context.rs#L783-L819","documentation":"`submit_python_job` accepts the compiled Python code only as a string; the second argument is coerced via `as_str()` and this error is thrown when it is not a string value. The library throws it because the adapter's `submit_python_job` method forwards the value directly and cannot accept other types.","triggerScenarios":"Calling `submit_python_job(model, some_non_string)` where compiled_code is e.g. a dict, a number, or an unset/undefined Minijinja value instead of the rendered Python source string.","commonSituations":"Passing a macro result object instead of its string; forgetting to `render()` or call the macro that produces the code; a variable holding `none` because compilation failed silently upstream.","solutions":["Pass the compiled code as a string, e.g. the rendered result of the python model's code macro.","If the value is an object, serialize/render it to a string before calling: `{% do submit_python_job(model, compiled_code | string) %}`.","Log/print the argument with `| string` in the template to verify it holds actual Python source."],"exampleFix":"-- before\n{% set code = my_python_code_macro(model) %}{% do submit_python_job(model, code) %}\n-- after\n{% set code = my_python_code_macro(model) | string %}{% do submit_python_job(model, code) %}\n","handlingStrategy":"type-guard","validationCode":"{% if compiled_code is not string %}\n  {% set compiled_code = compiled_code | string %}\n{% endif %}\n{% do submit_python_job(model, compiled_code) %}","typeGuard":"// minijinja\nfn is_string_value(v: &MinijinjaValue) -> bool { v.as_str().is_some() }","tryCatchPattern":"try:\n    submit_python_job(model, code)\nexcept Error as e:\n    if \"compiled_code must be a string\" in str(e):\n        raise ValueError(\"pass rendered python source as a string\") from e\n    raise","preventionTips":["Ensure the macro producing the code returns a string (pipe through | string if needed).","Check for None/undefined upstream compilation failures before calling.","Log the argument type during development with a debug print."],"tags":["jinja","type-mismatch","python-models"],"backgroundTag":"type-mismatch","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}