openai/codex · error · AgentGraphStoreError

invalid agent graph store request: {message}

Error message

invalid agent graph store request: {message}

What it means

An inject_request_headers entry selected secret_env_var as its secret source, but the value is empty or whitespace-only. The field holds the NAME of an environment variable (for example CODEX_GITHUB_TOKEN), not the token itself; the proxy resolves that variable at request time to build the header value, so a blank name can never resolve. Raised by validate_injected_headers during config validation.

Source

Thrown at codex-rs/agent-graph-store/src/error.rs:8

/// Result type returned by agent graph store operations.
pub type AgentGraphStoreResult<T> = Result<T, AgentGraphStoreError>;

/// Error type shared by agent graph store implementations.
#[derive(Debug, thiserror::Error)]
pub enum AgentGraphStoreError {
    /// The caller supplied invalid request data.
    #[error("invalid agent graph store request: {message}")]
    InvalidRequest {
        /// User-facing explanation of the invalid request.
        message: String,
    },

    /// Catch-all for implementation failures that do not fit a more specific category.
    #[error("agent graph store internal error: {message}")]
    Internal {
        /// User-facing explanation of the implementation failure.
        message: String,
    },
}

View on GitHub (pinned to 339751715c)

Solutions

  1. Set secret_env_var to a real variable name and export it before the proxy starts: secret_env_var = "CODEX_GITHUB_TOKEN"
  2. If the secret lives in a file instead, remove secret_env_var entirely and set secret_file to an absolute path
  3. Keep prefix = "Bearer " as-is; it is prepended to the resolved secret, not part of the name

Example fix

// config.toml — before
[[network.mitm_hooks.actions.inject_request_headers]]
name = "authorization"
secret_env_var = ""
prefix = "Bearer "

// after
[[network.mitm_hooks.actions.inject_request_headers]]
name = "authorization"
secret_env_var = "CODEX_GITHUB_TOKEN"
prefix = "Bearer "
Defensive patterns

Strategy: validation

Validate before calling

for header in &hook.actions.inject_request_headers {
    if let Some(var) = header.secret_env_var.as_deref() {
        if var.trim().is_empty() {
            return Err(anyhow!("{} has a blank secret_env_var", header.name));
        }
    }
}

Type guard

fn secret_env_var_valid(header: &InjectedHeaderConfig) -> bool {
    header.secret_env_var.as_deref().map_or(true, |v| !v.trim().is_empty())
}

Try / catch

match validate_mitm_hook_config(&config) {
    Ok(()) => {}
    Err(err) if err.to_string().contains("secret_env_var must not be empty") => { /* fill a real variable name */ }
    Err(err) => return Err(err),
}

Prevention

When it happens

Trigger: [[network.mitm_hooks.actions.inject_request_headers]] with name = "authorization", secret_env_var = "" (or a whitespace-only string), and no secret_file — validation aborts config load.

Common situations: A templating placeholder that was never replaced; the field left as an empty string after migrating from secret_file; the mistaken belief that the token value itself goes into this field.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


AI-assisted analysis of openai/codex@339751715c (2026-08-25). Data as JSON: /api/errors/f63875e84f8a276b. Report an issue: GitHub.