Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

generateStream: no empty-response guard, no fallback, and a raw provider error yielded as content

Open
#237 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 4 days

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
72/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
ai, backend

Research direction

Start in packages/outpost/ai/src/generator.ts:196-208 and compare generateStream with the generate behavior fixed by #223. Trace how pipeline.generateStreamingResponse consumes the yielded values, then use the #223 aimock recipe to cover an empty stream and the catch path. Done means empty responses receive the intended fallback behavior and provider errors are not emitted as ordinary content.

Written by the indexing model from the issue text.

Description

area: ai roadmap roadmap: next

Split out of #231, which carries this as a bullet rather than a tracked item. #223's review said "tracking with #228" — that reference is wrong: #228 is the QA chat SSE cross-chunk buffer bug in apps/web/src/hooks/use-qa-chat.ts, a different subject. So this has had no issue of its own.

generate() was fixed by #223 (merged as 825d0981): it now reads every text block and throws 'Model response contained no usable text' on none, caught by the never-crash fallback. generateStream has the same two defects, both unfixed.

1. No empty-response guard, and no fallback at all

packages/outpost/ai/src/generator.ts:196-206 yields only content_block_delta/text_delta events. A completion with no text yields nothing — the consumer sees a successful empty stream. There is no degraded signal on this path and no apology fallback, so it is strictly worse than the pre-#223 non-streaming behaviour, which at least returned an empty string a caller could test.

2. The catch yields a raw provider error as ordinary content

:207-208:

} catch (error) {
    yield `\n\n_Error generating response: ${error instanceof Error ? error.message : String(error)}_`;
}

That is provider error text placed into the response body. pipeline.generateStreamingResponse buffers what it yields, so a 500 becomes publishable content. Trap rather than live bug — no production caller reaches it today, which is also why it has stayed unnoticed. Overlaps #146 (the streaming path still reads the pre-#143 groundedness signal) and should probably be fixed in the same pass.

Why it hasn't bitten yet

generateStream's only caller is pipeline.generateStreamingResponse, which nothing in the queue invokes. The moment streaming is wired to a real channel, both defects are live.

Test gaps

No coverage for an empty stream and none for the catch path. Both are straightforward with the aimock recipe #223 used — the empty case needs a mocked stream that yields no text delta.

Dominant language
TypeScript
Stars
10
Forks
4
Avg merge
4d 2h
Merged PRs (30d)
7

Getting set up

  • Ships a Dockerfile or Docker Compose file
  • No pull request template
  • No contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from CopilotKit/outpost

All issues in CopilotKit/outpost

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.