openai/codex · error · std::io::Error
local cwd URI `{cwd_display}` is not absolute: {err}
Error message
local cwd URI `{cwd_display}` is not absolute: {err} What it means
The second-stage failure in guardian_cwd: for a LOCAL environment, PathUri::to_abs_path() failed, but the URL did convert to a filesystem path via to_file_path(); that path is then handed to AbsolutePathBuf::from_absolute_path_checked, which rejects non-absolute paths. This io::Error(InvalidInput) therefore means the URI produced a relative path — typically a file: URI without the leading slash or a dot/parent-relative form.
Source
Thrown at codex-rs/core/src/tools/approvals.rs:364
},
})
}
}
fn guardian_cwd(environment_id: &str, cwd: PathUri) -> std::io::Result<AbsolutePathBuf> {
match cwd.to_abs_path() {
Ok(cwd) => Ok(cwd),
Err(err) if environment_id != codex_exec_server::LOCAL_ENVIRONMENT_ID => Err(err),
Err(_) => {
let cwd_display = cwd.to_string();
let path = cwd.to_url().to_file_path().map_err(|()| {
std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("local cwd URI `{cwd_display}` is not a host-native path"),
)
})?;
AbsolutePathBuf::from_absolute_path_checked(path).map_err(|err| {
std::io::Error::new(
std::io::ErrorKind::InvalidInput,
format!("local cwd URI `{cwd_display}` is not absolute: {err}"),
)
})
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum ApprovalReviewer {
Guardian,
User,
}
impl ApprovalReviewer {
fn for_turn(turn: &TurnContext) -> Self {
Self::for_policy(turn.approval_policy(), turn.config.approvals_reviewer)
}View on GitHub (pinned to 339751715c)
Solutions
- Send an absolute file URI: file:/// + absolute path (three slashes, empty authority)
- Resolve the cwd against its base directory on the client before constructing the PathUri
- If consuming URIs from third parties, canonicalize/absolutize (std::fs::canonicalize) before conversion
Example fix
// before
let cwd = PathUri::from("file:projects/demo"); // → not absolute
// after
let cwd = PathUri::from(format!("file:///{}", abs_root.join("projects/demo").display())); Defensive patterns
Strategy: validation
Validate before calling
// Before sending: guarantee the URI path is absolute
fn absolute_file_uri(path: &std::path::Path) -> Option<String> {
if !path.is_absolute() { return None; }
let p = path.to_str()?.replace(' ', "%20");
Some(format!("file://{p}"))
} Type guard
fn uri_yields_absolute_path(cwd: &PathUri) -> bool {
cwd.to_url()
.to_file_path()
.ok()
.is_some_and(|p| p.is_absolute())
} Try / catch
match guardian_cwd(env_id, cwd.clone()) {
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput && e.to_string().contains("not absolute") => {
absolutize_and_retry(cwd) // join onto base dir, rebuild file:/// URI
}
r => r?,
} Prevention
- Always emit three slashes: file:///abs/path
- Resolve relative cwds against their base directory client-side before URI construction
- Unit-test URI builders to reject relative path components
When it happens
Trigger: An approval request with a local cwd PathUri like 'file:relative/path', 'file:./build', 'file:../repo', or any file URL whose path component does not begin with a root slash.
Common situations: Hand-built URIs joining a scheme onto a relative path; URI-encoding bugs dropping the leading '/'; clients assuming cwd is resolved against some base and sending it un-resolved.
Related errors
- local cwd URI `{cwd_display}` is not a host-native path
- pid-managed app-server shutdown is unsupported on this platf
- pid-managed updater shutdown is unsupported on this platform
- failed to read start time for pid-managed app server {pid}
- pid-managed app server {pid} has no recorded start time
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/678a7dc7fb7f6ed4.
Report an issue: GitHub.