Skip to content

SSE ping event fails to parse: EventSourceMessage.data is empty for ping events #20

Description

@hllshiro

Problem

When using dify-ai-provider with Dify API, SSE ping events (event: ping\n\n) cause a parse error in @ai-sdk/provider-utils's parseJsonEventStream. The error appears as a stream error in the console.

Root Cause

Dify API sends pings in SSE event-type format:

event: ping

But @ai-sdk/provider-utils parseJsonEventStream (used by createEventSourceResponseHandler) only destructures the data field from EventSourceMessage, discarding the event field:

// @ai-sdk/provider-utils parse-json-event-stream.ts
async transform({ data }, controller) {
  if (data === '[DONE]') return;
  controller.enqueue(await safeParseJSON({ text: data, schema }));
}

When event: ping\n\n arrives:

  • EventSourceParserStream produces { event: "ping", data: "" }
  • { data } destructuring yields empty string ""
  • safeParseJSON({ text: "", schema }) fails — empty string is not valid JSON
  • Transform enqueues error event

Why ping format changed

Dify uses event: ping (SSE event-type field) since commit 7753ba2d37 (April 2024). The ping string is a valid SSE event type per the SSE spec, not JSON data.

Suggested Fix

In the SSE transform within dify-chat-language-model.ts, before calling safeParseJSON, check if the message is a ping by inspecting the event field (or detecting empty data with a ping event type), and skip/enqueue a synthetic success result:

async transform({ event, data }, controller) {
  if (data === '[DONE]') return;
  // Handle ping events that have no JSON data
  if (event === 'ping' || (data === '' && event === 'ping')) {
    controller.enqueue({ success: true, value: { event: 'ping' } });
    return;
  }
  controller.enqueue(await safeParseJSON({ text: data, schema }));
}

Reproduction

  1. Configure any Dify app (chat/agent/workflow/completion) with streaming enabled
  2. Send a message and observe the console
  3. The event: ping SSE frames trigger parse errors from @ai-sdk/provider-utils

The existing switch case at dify-chat-language-model.ts:480 correctly handles { event: 'ping' }, but it's never reached because the transform fails before the case can match.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions