github/copilot-sdk · error
tool parameter schema must be a JSON object
Error message
tool parameter schema must be a JSON object
What it means
tool_parameters converts a JSON Schema object into an ordered parameter map and is the infallible convenience wrapper over try_tool_parameters. It panics via .expect() when the schema is not a JSON object (e.g. an array, string, or null), because a tool parameter schema must be an object per the MCP spec.
Solutions
- Use try_tool_parameters and handle the Err instead of panicking on dynamic input
- Ensure the schema is a JSON object before calling: verify value.is_object()
- Fix the schema construction so the top level is {"type":"object", ...}
- Validate schema files/inputs at load time before passing to tool_parameters
Example fix
// before
let params = tool_parameters(loaded_schema); // panics if loaded_schema isn't an object
// after
let params = try_tool_parameters(loaded_schema)
.expect("tool parameter schema must be a JSON object"); // or handle Err gracefully Defensive patterns
Strategy: validation
Validate before calling
// Rust
fn safe_tool_parameters(schema: serde_json::Value) -> Option<IndexMap<String, serde_json::Value>> {
if !schema.is_object() { return None; }
try_tool_parameters(schema).ok()
} Type guard
// Rust
fn is_json_object(v: &serde_json::Value) -> bool { v.is_object() } Prevention
- Always build schemas starting from json!({"type": "object"})
- Use try_tool_parameters for any schema from dynamic/external sources
- Validate schema files at load time
- Never pass serde_json::Value::Null as a schema
When it happens
Trigger: Calling tool_parameters with a JSON value that is not an object — serde_json::json!(null), a schema read from a file that is an array, or a dynamically built schema that ended up as something other than an object.
Common situations: Loading schemas from untrusted/dynamic sources; typos producing json!(["type","object"]) instead of json!({"type":"object"}); passing Value::Null when a schema is absent.
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
- JSON Schema serialization cannot fail
- schema must be a valid JSON object string
- schema cannot be combined with defaultValue — express…
- BuiltinPluginDirectories must contain only absolute paths
- URIConnection requires a non-empty URL
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/7764b1a61ce8d2e6.
Report an issue: GitHub.
Appendix: source
Thrown at rust/src/tool.rs:83
/// `serde_json::json!(...)` literal.
///
/// Use [`try_tool_parameters`] when the schema comes from dynamic input and
/// should return a recoverable error instead of panicking.
///
/// # Example
///
/// ```rust
/// use github_copilot_sdk::tool::tool_parameters;
/// use github_copilot_sdk::Tool;
///
/// let mut tool = Tool::default();
/// tool.name = "ping".to_string();
/// tool.description = "ping the server".to_string();
/// tool.parameters = tool_parameters(serde_json::json!({"type": "object"}));
/// # let _ = tool;
/// ```
pub fn tool_parameters(schema: serde_json::Value) -> IndexMap<String, serde_json::Value> {
try_tool_parameters(schema).expect("tool parameter schema must be a JSON object")
}
/// Fallible variant of [`tool_parameters`] for callers handling dynamic schema input.
pub fn try_tool_parameters(
schema: serde_json::Value,
) -> Result<IndexMap<String, serde_json::Value>, serde_json::Error> {
serde_json::from_value(schema)
}
/// Convert an MCP `CallToolResult` JSON value into a Copilot tool result.
///
/// Returns `None` when the value is not shaped like a `CallToolResult`.
pub fn convert_mcp_call_tool_result(value: &serde_json::Value) -> Option<ToolResult> {
let content = value.get("content")?.as_array()?;
let mut text_parts = Vec::new();
let mut binary_results = Vec::new();
for block in content {View on GitHub (pinned to cd8cf15dc3)