Skip to content

Docs: union sources document a per-source index: key that FindManyUnionSource does not have (TS2353) #385

Closed

Description

@MikeyZhang75

Summary

The pagination docs show a per-source index: { name, range } key inside union() sources. FindManyUnionSource has no such key — it exposes only where. Copying the documented example fails typecheck with TS2353.

Root cause

packages/kitcn/src/orm/types.ts:70-74:

export type FindManyUnionSource<
  TTableConfig extends TableRelationalConfig = TableRelationalConfig,
> = {
  where?: RelationsFilter<TTableConfig, any> | WhereCallback<TTableConfig>;
};

The docs show otherwise:

  • www/content/docs/orm/queries/pagination.mdx:139 and :145
  • packages/kitcn/skills/kitcn/references/features/orm.md:569 and :575

Both render a union source containing an index: block.

Impact

  • A user following the documented example gets TS2353: Object literal may only specify known properties, and 'index' does not exist in type 'FindManyUnionSource'.
  • The error is at least loud — the type system rejects it rather than silently ignoring it at runtime — so this is a documentation defect, not a data-correctness hazard.
  • The two doc surfaces are required to stay in sync (AGENTS.md: docs sync), so both need the same edit.

Suggested fix

Two options, and the choice depends on planned work:

  1. Correct the docs now — remove the index: block from both examples so they describe the shipped API.
  2. Implement the documented shape — add per-source index: { name, range } to FindManyUnionSource and honour it in _buildUnionSourceStream.

Option 2 is separately desirable (union sources currently cannot be index-anchored at all, so each source re-walks the shared index), but it is a larger change. If it is not imminent, do option 1 now rather than leaving the docs wrong.

Environment

  • kitcn 0.25.7
  • convex 1.44.0
  • verified at commit 471ec753

Activity

  1. self-assigned this
    on Aug 21, 2026
  2. MikeyZhang75 commented on Aug 21, 2026

    @MikeyZhang75
    CollaboratorAuthor

    Fixed in #394.

    Union sources now take a per-source index, so the documented example works as written:

    db.query.messages
      .select()
      .union([
        { index: { name: "by_from_to", range: (q) => q.eq("from", me).eq("to", them) } },
        { index: { name: "by_from_to", range: (q) => q.eq("from", them).eq("to", me) } },
      ])
      .interleaveBy(["createdAt", "id"])
      .paginate({ cursor: null, limit: 20 });

    To verify:

    1. Copy the example above against a table with a two-field index. It should typecheck — no TS2353.
    2. Run it. Each source reads only its own index range; rows outside both ranges are never read.
    3. Sources may name different indexes, as long as each pins its leading fields with eq so both end up ordered by the interleaveBy fields.
    4. A source with no index still falls back to a chain-level .withIndex(...), so existing where-only unions are unchanged.

    One thing worth flagging beyond the report: the other documented union form — a shared .withIndex(...) plus a per-source where — threw at runtime whenever interleaveBy listed fewer fields than the index. Those examples have been corrected too.

  3. added a commit that references this issue on Aug 29, 2026
    1317349
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions