{"record":{"id":"bc4d2fd9ca494986","repo":"zed-industries/zed","slug":"custom-tool-text-input-cannot-be-parsed-as-json","errorCode":null,"errorMessage":"custom tool text input cannot be parsed as JSON","messagePattern":"custom tool text input cannot be parsed as JSON","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/language_model_core/src/language_model_core.rs","lineNumber":503,"sourceCode":"            .min(MAXIMUM_BACKOFF),\n    )\n}\n\nfn is_invalid_encrypted_content_message(message: &str) -> bool {\n    let Ok(response) = serde_json::from_str::<serde_json::Value>(message) else {\n        return false;\n    };\n    response\n        .get(\"error\")\n        .and_then(|error| error.get(\"code\"))\n        .or_else(|| response.get(\"code\"))\n        .and_then(serde_json::Value::as_str)\n        == Some(\"invalid_encrypted_content\")\n}\n\n#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize)]\n#[serde(rename_all = \"snake_case\")]\npub enum StopReason {\n    EndTurn,\n    MaxTokens,\n    ToolUse,\n    Refusal,\n}\n\n#[derive(Debug, PartialEq, Clone, Copy, Serialize, Deserialize, Default)]\npub struct TokenUsage {\n    #[serde(default, skip_serializing_if = \"is_default\")]\n    pub input_tokens: u64,\n    #[serde(default, skip_serializing_if = \"is_default\")]\n    pub output_tokens: u64,\n    #[serde(default, skip_serializing_if = \"is_default\")]\n    pub cache_creation_input_tokens: u64,\n    #[serde(default, skip_serializing_if = \"is_default\")]\n    pub cache_read_input_tokens: u64,\n}\n","sourceCodeStart":485,"sourceCodeEnd":521,"githubUrl":"https://github.com/zed-industries/zed/blob/5a9b9558db01a6b906cec2fb70a797affdc58cdd/crates/language_model_core/src/language_model_core.rs#L485-L521","documentation":"Raised in LanguageModelToolUseInput::parse: the tool use arrived with freeform Text input rather than structured JSON, and the caller asked for a typed deserialization of it. Text inputs (e.g. from custom/freeform tools) can never satisfy a Deserialize bound, so this is a deterministic type mismatch — the caller used parse() on a tool whose input mode is text.","triggerScenarios":"Thrown at crates/language_model_core/src/language_model_core.rs:472 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check the input kind with as_json()/into_json() before calling parse and handle the Text variant separately","Only call parse::<T>() for tools declared with JSON input schemas","If the tool should emit JSON, fix the tool definition or prompt so the model produces structured input"],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"5a9b9558db01a6b906cec2fb70a797affdc58cdd","analyzedAt":"2026-08-20T19:29:52.058Z","contentChangedAt":"2026-08-20T19:29:52.058Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}