Skip to content

docs(sdk): wh.pipe(name).stream() documented as working but yields no events #445

Description

@EricAndrechek

The SDK docs present wh.pipe(name).stream() as a working live stream. It isn't — the connection opens and then silently receives nothing, forever.

Surfaced by the docs-reviewer gate while reviewing an unrelated CI branch.

The gap

Client side, clients/ts/src/pipes.ts:39-41 delegates straight to _createStream(this._name), which opens:

GET /v1/stream?table=<pipe-name>

Server side, internal/api/stream.go:50 derives the NATS subject as:

"ingest." + query.SafeEncodeNATS(table)

A pipe name matches no ingest.> subject, so the SSE connection establishes successfully and then delivers zero events. There is no error, no 404, no warning — it looks like a healthy but idle stream.

Where it's documented as working

  • docs/src/content/docs/sdk/pipes.md:26-28 — "Open a live stream. See Streaming"
  • docs/src/content/docs/sdk/reference.md:62-63 — listed in the API tree with no caveat
  • docs/src/content/docs/sdk/streaming.md:18 — names PipeRef among the valid .stream() sources, and caveats only the DLQ variant

Precedent

This is the same situation as wh.dlq.stream(), which was already fixed in docs — see CHANGELOG.md:67: "sdk.md stops presenting wh.dlq.stream() as working… caveated against #197 in all three places it appears". The pipe variant was missed in that sweep.

Also missing: test coverage

Nothing would catch this:

  • tests/e2e/sdk/streaming.test.ts only streams tables
  • clients/ts/src/pipes.test.ts:60 asserts delegation only — that .stream() calls _createStream with the pipe name, not that anything arrives

So the unit test passes precisely because it tests the broken call path's shape rather than its behaviour.

Suggested fix

Short term, match the DLQ treatment in all three doc locations:

Not functional server-side today: the SSE bridge carries ingest.> subjects only, so streaming a pipe name yields no events.

Longer term, decide whether pipe streaming should work at all. If yes, the stream handler needs a pipe-aware subject derivation (or pipes need to publish onto a streamable subject). If no, PipeRef.stream() should fail loudly — a client-side throw beats an SSE connection that hangs open delivering nothing.

Either way an e2e case that asserts events actually arrive (not just that a call was delegated) would keep it honest.

Activity

  1. coderabbitai commented on Aug 10, 2026

    @coderabbitai
    🔗 Related PRs

    #124 - chore(api)!: drop hub wildcard fan-out; SSE/WS use ?table= (closes #100) [merged]
    #174 - refactor(table names): handle unsafe table names [closed]
    #313 - feat(docs): view-transition polish, branded search + 404, chrome pass [closed]
    #330 - fix(pipes): escape non-scalar param values [closed]


    🧪 Issue enrichment is currently in open beta.

    You can configure auto-planning by selecting labels in the issue_enrichment configuration.

    To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

    issue_enrichment:
      auto_enrich:
        enabled: false

    💬 Have feedback or questions? Drop into our discord!

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

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions