Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions open-sse/utils/diagnostics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,26 @@ export function detectMalformedNonStream(resp: unknown): MalformedReason | null
return null;
}

// ── Claude API shape (native passthrough: type:"message" + content:[]) ──
if (body.type === "message") {
const content = body.content;
if (!Array.isArray(content) || content.length === 0) return "empty_choices";

const hasOutput = content.some((block: Record<string, unknown>) => {
if (block === null || typeof block !== "object") return false;
if (block.type === "text" && typeof block.text === "string" && block.text.length > 0)
return true;
if (block.type === "tool_use") return true;
if (block.type === "tool_result") return true;
return false;
});
Comment on lines +208 to +215

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The current implementation does not defensively check if block is a non-null object before accessing its properties (e.g., block.type). If the upstream response is malformed and contains non-object elements in the content array, this will throw a runtime TypeError and crash the request.

Additionally:

  1. The type assertion (block.text as string) is redundant because the typeof block.text === "string" check already narrows the type of block.text to string.
  2. Typing the callback parameter directly as Record<string, unknown> can cause compilation errors under strictFunctionTypes when the array element type is unknown.
    const hasOutput = (content as unknown[]).some((block) => {
      if (!block || typeof block !== "object") return false;
      const b = block as Record<string, unknown>;
      if (b.type === "text" && typeof b.text === "string" && b.text.length > 0) {
        return true;
      }
      if (b.type === "tool_use" || b.type === "tool_result") return true;
      return false;
    });


if (!hasOutput) return "empty_choices";
const stopReason = body.stop_reason;
if (stopReason === null) return "no_terminal";
return null;
}

// ── Chat Completions shape ──
const choices = body.choices;
if (!Array.isArray(choices) || choices.length === 0) return "empty_choices";
Expand Down
Loading