diff --git a/crates/arc-workflows/src/daytona_sandbox.rs b/crates/arc-workflows/src/daytona_sandbox.rs index 992e96bee..166550ca2 100644 --- a/crates/arc-workflows/src/daytona_sandbox.rs +++ b/crates/arc-workflows/src/daytona_sandbox.rs @@ -896,9 +896,29 @@ impl Sandbox for DaytonaSandbox { timeout: Some(std::time::Duration::from_millis(timeout_ms)), }; + // The Daytona toolbox API's ExecuteRequest does not support an `env` + // field, so we prepend `export` statements to inject env vars into the + // shell session before the actual command runs. + let command_with_env = if let Some(vars) = env_vars { + if !vars.is_empty() { + let exports: Vec = vars + .iter() + .map(|(k, v)| { + let escaped = v.replace('\'', "'\\''"); + format!("export {k}='{escaped}'") + }) + .collect(); + format!("{}\n{}", exports.join("\n"), command) + } else { + command.to_string() + } + } else { + command.to_string() + }; + // Wrap with `bash -c` so pipes, env vars, and shell features work. // The Daytona API uses direct exec, not a shell. - let wrapped = wrap_bash_command(command); + let wrapped = wrap_bash_command(&command_with_env); let result = process_svc .execute_command(&wrapped, options) .await