earendil-works/pi · error

Stream ended without finish_reason

Error message

Stream ended without finish_reason

What it means

Error "Stream ended without finish_reason" thrown in earendil-works/pi.

Source

Thrown at packages/ai/src/api/openai-completions.ts:652

			for (const block of blocks) {
				finishBlock(block);
			}
			if (options?.signal?.aborted) {
				throw new Error("Request was aborted");
			}

			if (output.stopReason === "aborted") {
				throw new Error("Request was aborted");
			}
			if (!hasFinishReason && !compat.supportsFinishReason) {
				output.stopReason = output.content.some((block) => block.type === "toolCall") ? "toolUse" : "stop";
			}
			if (output.stopReason === "error") {
				throw new Error(output.errorMessage || "Provider returned an error stop reason");
			}
			if ((compat.supportsFinishReason && !hasFinishReason) || output.stopReason === "pending") {
				throw new Error("Stream ended without finish_reason");
			}

			stream.push({ type: "done", reason: output.stopReason, message: output });
			stream.end();
		} catch (error) {
			for (const block of output.content) {
				delete (block as { index?: number }).index;
				// Streaming scratch buffers are only used during parsing; never persist them.
				delete (block as { partialArgs?: string }).partialArgs;
				delete (block as { customInput?: unknown }).customInput;
				delete (block as { streamIndex?: number }).streamIndex;
			}
			output.stopReason = options?.signal?.aborted ? "aborted" : "error";
			output.errorMessage = formatProviderError(normalizeProviderError(error));
			// Some providers via OpenRouter give additional information in this field.
			// normalizeProviderError already stringifies the parsed body (error.error)
			// into errorMessage, so only append the raw metadata when it is not already
			// present to avoid double-printing it.

View on GitHub (pinned to 4af9d21d3b)

Solutions

  1. Retry; check for a truncated stream that ended before finish_reason.

When it happens

Trigger: Thrown at packages/ai/src/api/openai-completions.ts:652 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of earendil-works/pi@4af9d21d3b (2026-08-24). Data as JSON: /api/errors/bbdbb9c1c466ec55. Report an issue: GitHub.