openai/codex · error · anyhow::Error
expected ServerNotification schema to be an object
Error message
expected ServerNotification schema to be an object
What it means
A build-time assertion inside add_server_notification_emitted_at_to_json_schema: the generated JSON schema for ServerNotification must be a JSON object (map of properties) so an `emittedAt` field can be injected into it for TypeScript export. It fires when the schema generator produced a non-object (e.g. a boolean or bare type reference) for ServerNotification, meaning the protocol type changed in a way the export script no longer expects.
Solutions
- Inspect the generated schema value in export.rs and confirm why ServerNotification serializes to a non-object schema (e.g. an untagged alias or a `$ref`-only schema).
- Update the TS export (add #[ts] attributes or adjust the type) so ServerNotification generates a proper object schema with properties.
- If the injection is obsolete, guard the mutation on as_object_mut() succeeding instead of erroring.
Defensive patterns
Strategy: type-guard
When it happens
Trigger: Thrown at codex-rs/app-server-protocol/src/export.rs:1377 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/1b968d3ae9e53c89.
Report an issue: GitHub.
Appendix: source
Thrown at codex-rs/app-server-protocol/src/export.rs:1377
.with_context(|| format!("Failed to write JSON schema for {file_stem}"))?;
}
let namespace = match raw_namespace {
Some("v1") | None => None,
Some(ns) => Some(ns.to_string()),
};
Ok(GeneratedSchema {
in_v1_dir: raw_namespace == Some("v1"),
namespace,
logical_name: logical_name.to_string(),
value: schema_value,
})
}
fn add_server_notification_emitted_at_to_json_schema(schema: &mut Value) -> Result<()> {
let schema = schema
.as_object_mut()
.ok_or_else(|| anyhow!("expected ServerNotification schema to be an object"))?;
schema.insert(
"properties".to_string(),
serde_json::json!({
"emittedAtMs": {
"description": "Unix timestamp (in milliseconds) when app-server emitted this notification.",
"format": "int64",
"type": "integer"
}
}),
);
// Keep this optional in generated client schemas for compatibility with
// older app-server versions. New servers still always emit it.
Ok(())
}
fn enforce_numbered_definition_collision_overrides(schema_name: &str, schema: &mut Value) {
for defs_key in ["definitions", "$defs"] {
let Some(defs) = schema.get(defs_key).and_then(Value::as_object) else {View on GitHub (pinned to 339751715c)