I defintely want it as useful as possible 🙏🙏🙏
Login to reply
Replies (2)
This is what Fugu said about the unexpected error you saw.
That error is a classic streaming vs. non-streaming mismatch, not a Routstr-vs-Fugu
incompatibility. Here’s what’s happening in plain terms.
## What the error means
The client received a streaming (SSE) response but tried to parse it as one JSON object.
An OpenAI-compatible streaming response looks like this on the wire:
data: {"id":"...","choices":[{"delta":{"content":"Hel"}}]}
data: {"id":"...","choices":[{"delta":{"content":"lo"}}]}
data: [DONE]
If code then calls something like JSON.parse(body) or response.json(), it hits the literal text
data: {"id"... and fails with exactly:
Unexpected token 'd', "data: {"id"... is not valid JSON
So the response is almost certainly fine — the client just isn’t reading it as a stream.
## The 3 likely causes (most to least common)
1. Client asked for a stream but parses it as JSON.
The request included "stream": true, but the code does await response.json() instead of reading
the SSE stream line-by-line. This is the #1 cause.
2. The request/tool defaults to streaming.
Some UIs, SDKs, or curl copy-paste snippets set stream: true by default. The user may not
realize it.
3. Upstream (Sakana Fugu) or Routstr is returning SSE even for a non-stream request.
Less likely, but worth ruling out — if Fugu always streams, Routstr passes that through, and a
client expecting a single JSON blob breaks.
## How to confirm quickly (no secrets in output)
Two safe tests. Use placeholder values; never paste your real key.
Test A — force non-streaming and expect one JSON object:
curl -s https://<your-routstr-node>/v1/chat/completions \
-H "Authorization: Bearer <cashu-or-api-token>" \
-H "Content-Type: application/json" \
-d '{"model":"fugu","messages":[{"role":"user","content":"hi"}],"stream":false}'
- If this returns a normal JSON object → your node works; the client just needs stream: false or
proper stream handling.
- If this still returns data: {...} lines → cause #3 (upstream/Routstr is forcing streaming), which
needs a config/handling fix.
Test B — explicitly stream and watch the SSE frames:
curl -N https://<your-routstr-node>/v1/chat/completions \
-H "Authorization: Bearer <cashu-or-api-token>" \
-H "Content-Type: application/json" \
-d '{"model":"fugu","messages":[{"role":"user","content":"hi"}],"stream":true}'
- You should see multiple data: {...} lines ending in data: [DONE]. That confirms streaming is
working correctly and the client is the thing that must change.
## The fix (depends on what Test A shows)
If Test A returns clean JSON (most likely):
The client is the problem. Two options:
- Easiest: send "stream": false and keep using response.json().
- Or handle the stream properly. Example (Node/JS):
const res = await fetch(url, { method: "POST", headers, body });
const reader = res.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
const { value, done } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
for (const line of buffer.split("\n")) {
const s = line.trim();
if (!s.startsWith("data:")) continue;
const payload = s.slice(5).trim();
if (payload === "[DONE]") break;
const json = JSON.parse(payload); // parse each frame, not the whole body
process.stdout.write(json.choices?.[0]?.delta?.content ?? "");
}
}
With the OpenAI SDK, just use the streaming iterator instead of awaiting a single response:
const stream = await client.chat.completions.create({ model: "fugu", messages, stream: true });
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
If Test A still streams (cause #3):
Then the node/upstream is forcing SSE. In that case I’d want to check how your Routstr node is
configured and how Fugu is being called, because Routstr should honor the client’s stream flag
rather than always streaming.
## Question so I can pin it down
Can you tell me:
1. What is the client? (a website/chat UI, the OpenAI SDK, curl, LangChain, something else?)
2. Was stream: true set in the request (or is it a UI you don’t control)?
3. Can you run Test A above and tell me whether it returns clean JSON or data: {...} lines?
That single Test A result tells us definitively whether this is a client-side parsing bug (easy) or
a node/upstream streaming config issue (needs a look at your Routstr + Fugu setup).
Thanks for the details, will look into it and keep u updated ..