Skip to main content

codex/
error.rs

1use std::{path::PathBuf, process::ExitStatus, time::Duration};
2
3use thiserror::Error;
4
5/// Errors that may occur while invoking the Codex CLI.
6#[derive(Debug, Error)]
7pub enum CodexError {
8    #[error("codex binary `{binary}` could not be spawned: {source}")]
9    Spawn {
10        binary: PathBuf,
11        #[source]
12        source: std::io::Error,
13    },
14    #[error("failed to wait for codex process: {source}")]
15    Wait {
16        #[source]
17        source: std::io::Error,
18    },
19    #[error("codex exceeded timeout of {timeout:?}")]
20    Timeout { timeout: Duration },
21    #[error("codex exited with {status:?}: {stderr}")]
22    NonZeroExit { status: ExitStatus, stderr: String },
23    #[error("codex output was not valid UTF-8: {0}")]
24    InvalidUtf8(#[from] std::string::FromUtf8Error),
25    #[error("failed to parse {context} JSON output: {source}")]
26    JsonParse {
27        context: &'static str,
28        stdout: String,
29        #[source]
30        source: serde_json::Error,
31    },
32    #[error("failed to parse execpolicy JSON output: {source}")]
33    ExecPolicyParse {
34        stdout: String,
35        #[source]
36        source: serde_json::Error,
37    },
38    #[error("failed to parse features list output: {reason}")]
39    FeatureListParse { reason: String, stdout: String },
40    #[error("failed to read responses-api-proxy server info from `{path}`: {source}")]
41    ResponsesApiProxyInfoRead {
42        path: PathBuf,
43        #[source]
44        source: std::io::Error,
45    },
46    #[error("failed to parse responses-api-proxy server info from `{path}`: {source}")]
47    ResponsesApiProxyInfoParse {
48        path: PathBuf,
49        #[source]
50        source: serde_json::Error,
51    },
52    #[error("prompt must not be empty")]
53    EmptyPrompt,
54    #[error("sandbox command must not be empty")]
55    EmptySandboxCommand,
56    #[error("execpolicy command must not be empty")]
57    EmptyExecPolicyCommand,
58    #[error("API key must not be empty")]
59    EmptyApiKey,
60    #[error("task id must not be empty")]
61    EmptyTaskId,
62    #[error("environment id must not be empty")]
63    EmptyEnvId,
64    #[error("MCP server name must not be empty")]
65    EmptyMcpServerName,
66    #[error("MCP server command must not be empty")]
67    EmptyMcpCommand,
68    #[error("MCP server URL must not be empty")]
69    EmptyMcpUrl,
70    #[error("socket path must not be empty")]
71    EmptySocketPath,
72    #[error("failed to create temporary working directory: {0}")]
73    TempDir(#[source] std::io::Error),
74    #[error("failed to resolve working directory: {source}")]
75    WorkingDirectory {
76        #[source]
77        source: std::io::Error,
78    },
79    #[error("failed to prepare app-server output directory `{path}`: {source}")]
80    PrepareOutputDirectory {
81        path: PathBuf,
82        #[source]
83        source: std::io::Error,
84    },
85    #[error("failed to prepare CODEX_HOME at `{path}`: {source}")]
86    PrepareCodexHome {
87        path: PathBuf,
88        #[source]
89        source: std::io::Error,
90    },
91    #[error("codex stdout unavailable")]
92    StdoutUnavailable,
93    #[error("codex stderr unavailable")]
94    StderrUnavailable,
95    #[error("codex stdin unavailable")]
96    StdinUnavailable,
97    #[error("failed to capture codex output: {0}")]
98    CaptureIo(#[from] std::io::Error),
99    #[error("failed to write prompt to codex stdin: {0}")]
100    StdinWrite(#[source] std::io::Error),
101    #[error("failed to join codex output task: {0}")]
102    Join(#[from] tokio::task::JoinError),
103}