Commit bd9e1a12 for whisper.cpp

commit bd9e1a12352fa57e448bdea6a0649aa9c24c64aa
Author: DrMkdaddy <37319157+DrMkdaddy@users.noreply.github.com>
Date:   Mon Nov 9 05:02:33 2026 -0800

    server : handle missing language id when VAD removes all audio (#4158)

    whisper_lang_auto_detect() returns -2 when VAD removes all audio, whisper_lang_str_full(-2) returns null, and lang_probs[-2] reads out of bounds. verbose_json then returns 500.

    Fall back to "unknown" with probability 0 for the detected language, and use the same fallback for the language fields.

diff --git a/examples/server/server.cpp b/examples/server/server.cpp
index 8e8f9bd9..9ef0205f 100644
--- a/examples/server/server.cpp
+++ b/examples/server/server.cpp
@@ -451,6 +451,11 @@ void whisper_print_segment_callback(struct whisper_context * ctx, struct whisper
     }
 }

+static const char * whisper_lang_str_or_unknown(int lang_id) {
+    const char * language = whisper_lang_str_full(lang_id);
+    return language != nullptr ? language : "unknown";
+}
+
 std::string output_str(struct whisper_context * ctx, const whisper_params & params, const std::vector<std::vector<float>> & pcmf32s) {
     std::stringstream result;
     const int n_segments = whisper_full_n_segments(ctx);
@@ -1065,9 +1070,10 @@ int main(int argc, char ** argv) {
         } else if (params.response_format == vjson_format) {
             /* try to match openai/whisper's Python format */
             std::string results = output_str(ctx, params, pcmf32s);
+            const char * language = whisper_lang_str_or_unknown(whisper_full_lang_id(ctx));
             json jres = json{
                 {"task", params.translate ? "translate" : "transcribe"},
-                {"language", whisper_lang_str_full(whisper_full_lang_id(ctx))},
+                {"language", language},
                 {"duration", float(pcmf32.size())/WHISPER_SAMPLE_RATE},
                 {"text", results},
                 {"segments", json::array()}
@@ -1076,8 +1082,13 @@ int main(int argc, char ** argv) {
             if (!params.no_language_probabilities) {
                 std::vector<float> lang_probs(whisper_lang_max_id() + 1, 0.0f);
                 const auto detected_lang_id = whisper_lang_auto_detect(ctx, 0, params.n_threads, lang_probs.data());
-                jres["detected_language"] = whisper_lang_str_full(detected_lang_id);
-                jres["detected_language_probability"] = lang_probs[detected_lang_id];
+                if (detected_lang_id < 0 || detected_lang_id > whisper_lang_max_id()) {
+                    jres["detected_language"]             = "unknown";
+                    jres["detected_language_probability"] = 0.0f;
+                } else {
+                    jres["detected_language"]             = whisper_lang_str_full(detected_lang_id);
+                    jres["detected_language_probability"] = lang_probs[detected_lang_id];
+                }
                 jres["language_probabilities"] = json::object();
                 // Add all language probabilities
                 for (int i = 0; i <= whisper_lang_max_id(); ++i) {
@@ -1166,7 +1177,7 @@ int main(int argc, char ** argv) {
                 {"text", results}
             };
             if (params.detect_language) {
-                jres["language"] = whisper_lang_str_full(whisper_full_lang_id(ctx));
+                jres["language"] = whisper_lang_str_or_unknown(whisper_full_lang_id(ctx));
             }
             res.set_content(jres.dump(-1, ' ', false, json::error_handler_t::replace),
                             "application/json");