gitbutlerapp/gitbutler · warning · Error

Received empty response from AI service

Error message

Received empty response from AI service

What it means

Thrown after the AI credential check's generation test finishes: result is set from aiResult || streamingResult || null, and if it is null or only whitespace the service technically responded but produced no usable commit message.

Source

Thrown at apps/desktop/src/components/settings/AiCredentialCheck.svelte:149

					// Append each token as it comes in
					streamingResult += token;
				},
			});

			// Clear the timeout since we got a result
			if (testTimeout) {
				clearTimeout(testTimeout);
				testTimeout = null;
			}

			// Set the final result (handling undefined case)
			result = aiResult || streamingResult || null;

			debugInfo += `, Received commit message: ${result?.substring(0, 30)}${result && result.length > 30 ? "..." : ""}`;

			// If result is empty or undefined, show an error
			if (!result || result.trim() === "") {
				throw new Error("Received empty response from AI service");
			}
		} catch (e) {
			console.error("AI credential check error:", e);

			// Don't show abort errors as they're expected when we cancel the request
			if (e instanceof Error && e.name === "AbortError") {
				error = "AI request was cancelled";
			} else {
				error = e instanceof Error ? e.message : "Unknown error occurred";
			}

			debugInfo += `, Error: ${error}`;

			// Clear the timeout if there was an error
			if (testTimeout) {
				clearTimeout(testTimeout);
				testTimeout = null;
			}

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Retry the test once — empty completions from local models are often transient.
  2. For local backends, verify a model is actually loaded and can answer a trivial prompt (curl the endpoint directly).
  3. Shorten/repair the prompt source: ensure there are staged changes for the model to describe.
  4. If it persists, capture the raw provider response in devtools to see whether the service truly returned empty content.
Defensive patterns

Strategy: retry

Validate before calling

const candidate = aiResult || streamingResult || "";
if (candidate.trim() === "") {
  // retry once before surfacing the error to the user
  retried = true;
  await generate();
}

Try / catch

try {
  await runCheck();
} catch (e) {
  if (e instanceof Error && e.message === "Received empty response from AI service" && !retriedOnce) {
    retriedOnce = true;
    await runCheck(); // local models often return an empty completion once
  } else {
    error = e instanceof Error ? e.message : "Unknown error occurred";
  }
}

Prevention

When it happens

Trigger: The test generation call completed (or timed out into an empty stream result) yielding '' or undefined: model returned an empty completion, the stream produced no chunks before finishing, or the response shape changed so both result variables stayed unset.

Common situations: Ollama/LM Studio answered but returned an empty completion (model not loaded, context overflow); hosted API returned an empty choice; content-filtered response; frontend/backend contract drift where the generated text field moved.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/72ab06989547f518. Report an issue: GitHub.