{"record":{"id":"59cd0ce44ac6cfc7","repo":"Hmbown/CodeWhale","slug":"fim-completion-is-not-supported-for-because-the","errorCode":null,"errorMessage":"FIM completion is not supported for {} because the route has no proven FIM wire contract ({:?})","messagePattern":"FIM completion is not supported for (.+?) because the route has no proven FIM wire contract \\((.+?)\\)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/tui/src/client.rs","lineNumber":3713,"sourceCode":"        reasoning_tokens,\n        reasoning_replay_tokens: None,\n        server_tool_use,\n    }\n}\n\nimpl DeepSeekClient {\n    /// Call the DeepSeek `/beta/completions` FIM endpoint.\n    pub async fn fim_completion(\n        &self,\n        model: &str,\n        prompt: &str,\n        suffix: &str,\n        max_tokens: u32,\n    ) -> anyhow::Result<String> {\n        if self.api_provider == ApiProvider::OpencodeZen\n            || self.wire_format != WireFormat::ChatCompletions\n        {\n            bail!(\n                \"FIM completion is not supported for {} because the route has no proven FIM wire contract ({:?})\",\n                self.api_provider.display_name(),\n                self.wire_format\n            );\n        }\n        let url = api_url_with_suffix(&self.base_url, \"beta/completions\", None);\n        let model = wire_model_for_provider_route(self.api_provider, &self.base_url, model);\n        let max_tokens = max_tokens.min(self.effective_max_output_tokens(&model));\n        let body = json!({\n            \"model\": model,\n            \"prompt\": prompt,\n            \"suffix\": suffix,\n            \"max_tokens\": max_tokens,\n        });\n        let response = self.send_json_with_retry(&url, &body).await?;\n        let status = response.status();\n        if !status.is_success() {\n            let raw_error_text = bounded_error_text(response, ERROR_BODY_MAX_BYTES).await;","sourceCodeStart":3695,"sourceCodeEnd":3731,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/tui/src/client.rs#L3695-L3731","documentation":"`DeepSeekClient::fim_completion` calls the DeepSeek `/beta/completions` FIM (fill-in-the-middle) endpoint, and it only trusts that wire contract for direct ChatCompletions routes. It bails up front when the provider is `OpencodeZen` or the wire format is anything other than `ChatCompletions`, because no proven FIM contract exists for those routes. No HTTP request is made; the check fails fast at the client boundary.","triggerScenarios":"Invoking `fim_completion(model, prompt, suffix, max_tokens)` when `api_provider == ApiProvider::OpencodeZen`, or when `wire_format` is `AnthropicMessages` / `OpenAiResponses` / any non-ChatCompletions format.","commonSituations":"Enabling autocomplete/FIM while the default provider routes through opencode zen. Pointing the client at an OpenAI-compatible gateway that negotiates a different wire format. Config entries that inherit the zen provider for the autocomplete lane.","solutions":["Route FIM requests through a dedicated direct DeepSeek (or DeepSeek-compatible) provider configured with `wire_format = \"chat-completions\"`","Disable FIM/autocomplete for zen and non-ChatCompletions routes instead of calling it","Add a separate provider entry for completion work with its own base_url pointing at DeepSeek directly"],"exampleFix":"// before (provider = OpencodeZen -> bail)\nlet text = client.fim_completion(model, prefix, suffix, 256).await?;\n\n// after: use a direct DeepSeek ChatCompletions client for FIM\nlet fim_client = deepseek_client_for(base_url, api_key); // wire_format = ChatCompletions\nlet text = fim_client.fim_completion(model, prefix, suffix, 256).await?;","handlingStrategy":"validation","validationCode":"if client.api_provider == ApiProvider::OpencodeZen\n    || client.wire_format != WireFormat::ChatCompletions\n{\n    return Ok(None); // skip FIM on this route\n}\nlet completion = client.fim_completion(model, prefix, suffix, max).await?;","typeGuard":"fn route_supports_fim(provider: ApiProvider, wire: WireFormat) -> bool {\n    provider != ApiProvider::OpencodeZen && wire == WireFormat::ChatCompletions\n}","tryCatchPattern":"match client.fim_completion(model, prefix, suffix, max).await {\n    Ok(text) => insert(text),\n    Err(err) if err.to_string().contains(\"no proven FIM wire contract\") => {\n        skip_autocomplete(); // expected on zen/non-chat routes\n    }\n    Err(err) => log_and_disable_autocomplete(err),\n}","preventionTips":["Configure a dedicated direct-DeepSeek provider entry for autocomplete/FIM","Never route FIM through opencode zen or non-ChatCompletions wire formats","Feature-flag autocomplete per provider rather than globally"],"tags":["fim","deepseek","autocomplete","opencode-zen","wire-format","rust"],"backgroundTag":"unsupported-provider-feature","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}