openai/codex · error · anyhow::Error
Agent Identity only supports production and staging ChatGPT
Error message
Agent Identity only supports production and staging ChatGPT environments
What it means
parse_header_name feeds the configured string to rama_http's HeaderName::from_bytes, which accepts only RFC 7230 token characters: ASCII letters and digits plus !#$%&'*+-.^_`|~. Spaces, colons, other delimiters, control bytes, non-ASCII characters, or an empty string all fail. The helper is shared by match.headers keys, strip_request_headers entries, and inject_request_headers names, and runs during both validation and hook compilation.
Source
Thrown at codex-rs/agent-identity/src/lib.rs:70
Staging,
}
impl ChatGptEnvironment {
pub fn from_chatgpt_base_url(chatgpt_base_url: &str) -> Result<Self> {
match chatgpt_base_url.trim_end_matches('/') {
"https://chatgpt.com"
| "https://chatgpt.com/backend-api"
| "https://chatgpt.com/codex"
| "https://chatgpt.com/backend-api/codex"
| "https://chat.openai.com"
| "https://chat.openai.com/backend-api"
| "https://chat.openai.com/codex"
| "https://chat.openai.com/backend-api/codex" => Ok(Self::Production),
"https://chatgpt-staging.com"
| "https://chatgpt-staging.com/backend-api"
| "https://chatgpt-staging.com/codex"
| "https://chatgpt-staging.com/backend-api/codex" => Ok(Self::Staging),
_ => anyhow::bail!(
"Agent Identity only supports production and staging ChatGPT environments"
),
}
}
pub fn chatgpt_base_url(self) -> &'static str {
match self {
Self::Production => "https://chatgpt.com/backend-api",
Self::Staging => "https://chatgpt-staging.com/backend-api",
}
}
pub fn agent_identity_authapi_base_url(self) -> &'static str {
match self {
Self::Production => PROD_AGENT_IDENTITY_AUTHAPI_BASE_URL,
Self::Staging => STAGING_AGENT_IDENTITY_AUTHAPI_BASE_URL,
}
}View on GitHub (pinned to 339751715c)
Solutions
- Keep the bare token form of the name: authorization, x-custom-header
- Strip a trailing colon or surrounding whitespace from names copied out of header lines
- Verify names programmatically with the same rule: http::HeaderName::from_bytes(name.as_bytes()).is_ok()
Example fix
// config.toml — before strip_request_headers = ["Authorization:"] // after strip_request_headers = ["authorization"]
Defensive patterns
Strategy: type-guard
Validate before calling
let bad: Vec<_> = hook.actions.strip_request_headers.iter()
.chain(hook.matcher.headers.keys().map(String::as_str))
.filter(|n| !is_valid_header_name(n))
.collect();
if !bad.is_empty() {
return Err(anyhow!("invalid header names: {bad:?}"));
} Type guard
fn is_valid_header_name(name: &str) -> bool {
http::HeaderName::from_bytes(name.as_bytes()).is_ok()
} Try / catch
let name = HeaderName::from_bytes(raw.as_bytes())
.map_err(|err| anyhow!("invalid header name {raw:?}: {err}"))?; Prevention
- Copy header names without the trailing colon from header lines
- Trim names before writing them to config
- Unit-test config fixtures against the same RFC 7230 token rule
When it happens
Trigger: strip_request_headers = ["Authorization:"] (trailing colon copied from a header line), a match.headers key like "X-Custom Header" (space), name = "" (empty), or a non-ASCII name such as a localized header. Any of these aborts validate_mitm_hook_config or the later compile step.
Common situations: Pasting 'Authorization: Bearer x' and keeping the colon; smart quotes or invisible unicode introduced by docs/chat paste; whitespace or CRLF artifacts in generated configs.
Related errors
- Unsupported platform: ${platform} (${arch})
- Unsupported target triple: ${targetTriple}
- Missing optional dependency ${platformPackage}. Reinstall Co
- invalid agent graph store request: {message}
- agent graph store internal error: {message}
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/80e503b6dd6d94c5.
Report an issue: GitHub.