From c17a9f3891fa952557e7ba21cd9349fd8482a30d Mon Sep 17 00:00:00 2001 From: Thomas Marchand Date: Sat, 17 Jan 2026 13:58:32 +0000 Subject: [PATCH] Fix broken context symlink in container workspaces For chroot workspaces, the context symlink was pointing to the host path (e.g., /root/.openagent/workspaces/xxx/context/mission-id) which doesn't exist inside the container. Now it points to the container path (/root/context/mission-id) where the directory is bind-mounted. Also ensures the mission context directory is created on the host before the container starts, so the bind mount isn't empty. --- src/workspace.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/workspace.rs b/src/workspace.rs index 09661dd..9845a8a 100644 --- a/src/workspace.rs +++ b/src/workspace.rs @@ -1431,12 +1431,25 @@ pub async fn write_runtime_workspace_state( tokio::fs::create_dir_all(&runtime_dir).await?; let context_root = working_dir_root.join(context_dir_name); let mission_context = mission_id.map(|id| context_root.join(id.to_string())); + // Create the mission context directory on the host so it exists when bind-mounted + if let Some(target) = mission_context.as_ref() { + tokio::fs::create_dir_all(target).await?; + } let context_link = working_dir.join(context_dir_name); if let Some(target) = mission_context.as_ref() { if !context_link.exists() { #[cfg(unix)] { - if let Err(e) = std::os::unix::fs::symlink(target, &context_link) { + // For chroot workspaces, the symlink must point to the container path + // since /root/context is bind-mounted, not the host path + let symlink_target = if workspace.workspace_type == WorkspaceType::Chroot { + PathBuf::from("/root") + .join(context_dir_name) + .join(mission_id.unwrap().to_string()) + } else { + target.clone() + }; + if let Err(e) = std::os::unix::fs::symlink(&symlink_target, &context_link) { tracing::warn!( workspace = %workspace.name, mission = ?mission_id,