openai/codex · error · anyhow::Error
expected bundle root to be an object
Error message
expected bundle root to be an object
What it means
build_flat_v2_schema flattens the merged JSON Schema bundle for datamodel-code-generator, which only walks one level of definitions. Its first guard requires the bundle root to be a JSON object. The production merge step always returns an object with $schema, title, type, and definitions, so this error means the function received something that step would not produce: a hand-built fixture, a raw sub-schema, or a transformed Value.
Source
Thrown at codex-rs/app-server-protocol/src/export.rs:1091
Ok(Value::Object(root))
}
/// Build a datamodel-code-generator-friendly v2 bundle from the mixed export.
///
/// The full bundle keeps v2 schemas nested under `definitions.v2`, plus a few
/// shared root definitions like `ClientRequest` and `ServerNotification`.
/// Python codegen only walks one definitions map level, so
/// a direct feed would treat `v2` itself as a schema and miss unreferenced v2
/// leaves. This helper flattens all v2 definitions to the root definitions map,
/// then pulls in the shared root schemas and any non-v2 transitive deps they
/// still reference. Keep the shared root unions intact here: some valid
/// request/notification/event variants are inline or only reference shared root
/// helpers, so filtering them by the presence of a `#/definitions/v2/` ref
/// would silently drop real API surface from the flat bundle.
fn build_flat_v2_schema(bundle: &Value) -> Result<Value> {
let Value::Object(root) = bundle else {
return Err(anyhow!("expected bundle root to be an object"));
};
let definitions = root
.get("definitions")
.and_then(Value::as_object)
.ok_or_else(|| anyhow!("expected bundle definitions map"))?;
let v2_definitions = definitions
.get("v2")
.and_then(Value::as_object)
.ok_or_else(|| anyhow!("expected v2 namespace in bundle definitions"))?;
let mut flat_root = root.clone();
let title = root
.get("title")
.and_then(Value::as_str)
.unwrap_or("CodexAppServerProtocol");
let mut flat_definitions = v2_definitions.clone();
let mut shared_definitions = Map::new();
let mut non_v2_refs = HashSet::new();View on GitHub (pinned to 339751715c)
Solutions
- Pass a bundle shaped like the merge step output: an object with $schema, title, type object, and definitions keys.
- In tests, build the fixture through the real merge path or at minimum wrap it as json!({"definitions": {...}}).
- If it fires in a production path, the upstream invariant at the merge step broke; diff recent changes around the bundle construction.
Example fix
// before
let flat = build_flat_v2_schema(&json!([{"definitions": {}}]))?; // array root: error
// after
let flat = build_flat_v2_schema(&json!({
"definitions": {"v2": {}}
}))?; Defensive patterns
Strategy: type-guard
Validate before calling
// Call-site check before flattening:
if !is_flat_bundle_input(&bundle) {
return Err(anyhow!("bundle producer must emit an object with a definitions map"));
} Type guard
fn is_flat_bundle_input(v: &serde_json::Value) -> bool {
v.as_object().is_some_and(|root| {
root.get("definitions").is_some_and(serde_json::Value::is_object)
})
} Prevention
- Generate test fixtures through the real merge step instead of hand-written Values.
- Keep the bundle contract (object root with a definitions map) documented at the producer.
- Treat these guards as fail-fast checks: fix the producer rather than catching the error.
When it happens
Trigger: Calling build_flat_v2_schema with a Value whose root is an array, string, number, or null: unit-test fixtures crafted with json!, or a refactor that feeds a schemars sub-schema or a definitions array instead of the merged bundle object.
Common situations: Writing tests for the flat-v2 flattening with minimal ad-hoc inputs; refactors of generate_json_with_experimental that change what is passed to the flattener.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- expected bundle definitions map
- expected v2 namespace in bundle definitions
- TypeScript header worker panicked
- Prettier failed with status {status}
- generated input schema for {name} should parse: {err}
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/64606335daf403cc.
Report an issue: GitHub.