mirror of
https://github.com/openai/codex.git
synced 2026-09-05 15:18:41 +00:00
Preserve sandbox errors during session initialization (#40381)
## Why On macOS, rejecting a symlinked writable root during sandbox setup could be misreported as corrupt session data because both paths surfaced an `InvalidInput` I/O error. ## What changed - Treat only `InvalidData` errors as evidence of corrupt session storage. - Preserve `InvalidInput` failures so the original sandbox preparation error and its actionable details reach the user. ## Testing Add a macOS regression test that configures a symlinked writable root and verifies thread creation reports the sandbox failure without suggesting that session data is corrupt. GitOrigin-RevId: 2b83d9f92a517407b88c21b471fa8bff5fd20d1d
This commit is contained in:
@@ -50,7 +50,7 @@ fn map_rollout_io_error(io_err: &std::io::Error, codex_home: &Path) -> Option<Co
|
||||
"Session storage path {} is blocked by an existing file. Remove or rename it so Codex can create sessions.",
|
||||
sessions_dir.display()
|
||||
),
|
||||
ErrorKind::InvalidData | ErrorKind::InvalidInput => format!(
|
||||
ErrorKind::InvalidData => format!(
|
||||
"Session data under {} looks corrupt or unreadable. Clearing the sessions directory may help (this will remove saved threads).",
|
||||
sessions_dir.display()
|
||||
),
|
||||
|
||||
@@ -681,6 +681,57 @@ async fn denied_project_instructions_fail_thread_creation() -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn symlinked_writable_root_reports_sandbox_failure_instead_of_session_corruption()
|
||||
-> Result<()> {
|
||||
let server = start_mock_server().await;
|
||||
let home = Arc::new(TempDir::new()?);
|
||||
let visualization_target = home.path().join("visualization-target");
|
||||
std::fs::create_dir(&visualization_target)?;
|
||||
let visualization_root = home.path().join("visualizations");
|
||||
create_directory_symlink(&visualization_target, &visualization_root);
|
||||
|
||||
let mut builder = test_codex().with_home(home).with_config(move |config| {
|
||||
let mut file_system_policy = FileSystemSandboxPolicy::read_only();
|
||||
file_system_policy.entries.push(FileSystemSandboxEntry::new(
|
||||
config.cwd.join("private.txt").into(),
|
||||
FileSystemAccessMode::Deny,
|
||||
));
|
||||
file_system_policy.entries.push(FileSystemSandboxEntry::new(
|
||||
visualization_root.abs().into(),
|
||||
FileSystemAccessMode::Write,
|
||||
));
|
||||
config
|
||||
.permissions
|
||||
.set_permission_profile(PermissionProfile::from_runtime_permissions(
|
||||
&file_system_policy,
|
||||
NetworkSandboxPolicy::Restricted,
|
||||
))
|
||||
.expect("test config should allow the restricted filesystem policy");
|
||||
});
|
||||
|
||||
let error = match builder.build(&server).await {
|
||||
Ok(_) => anyhow::bail!("thread creation must reject the symlinked writable root"),
|
||||
Err(error) => format!("{error:#}"),
|
||||
};
|
||||
|
||||
assert!(
|
||||
error.contains("failed to prepare fs sandbox"),
|
||||
"thread creation should report the sandbox preparation failure: {error}"
|
||||
);
|
||||
assert!(
|
||||
error.contains("symlinked writable roots are not supported"),
|
||||
"thread creation should preserve the rejected writable root: {error}"
|
||||
);
|
||||
assert!(
|
||||
!error.contains("Session data under"),
|
||||
"sandbox preparation failure should not be diagnosed as session corruption: {error}"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Tightening permissions fails the turn before stale project instructions reach the model.
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn tightening_environment_read_permissions_invalidates_cached_project_instructions()
|
||||
|
||||
Reference in New Issue
Block a user