🐛 Bug: a2ui-renderer: RendererProps.children is typed (id) => ReactNode, but list templates need (id, basePath) · Issue #7800 · CopilotKit/CopilotKit · GitHub
Skip to content

🐛 Bug: a2ui-renderer: RendererProps.children is typed (id) => ReactNode, but list templates need (id, basePath) #7800

Closed

Description

@Laptopmini

♻️ Reproduction Steps

A custom catalog whose list component uses a ChildList template:

const definitions = {
  PartList: { props: z.object({ items: CommonSchemas.ChildList }) },
  PartRow: { props: z.object({ name: CommonSchemas.DynamicString }) },
};

const catalog = createCatalog(definitions, {
  PartList: ({ props, children }) => (
    <ul>
      {(props.items as unknown as { id: string; basePath?: string }[]).map((node) => (
        // (a) children(node.id)                 -> compiles, renders empty
        // (b) children(node.id, node.basePath)  -> renders, fails tsc (TS2554)
        <li key={node.basePath}>{children(node.id)}</li>
      ))}
    </ul>
  ),
  PartRow: ({ props }) => <span>{String(props.name ?? "")}</span>,
});

// components: root = PartList { items: { componentId: "row", path: "/parts" } },
//             row  = PartRow  { name: { path: "name" } }
// data:       { parts: [{ name: "Bolt A" }, { name: "Bolt B" }] }

✅ Expected Behavior

The renderer can forward each item's basePath with no type error, and the list shows "Bolt A" and "Bolt B".

❌ Actual Behavior

  • (a) children(node.id) compiles, but each row resolves name against the surface root, so the list renders with empty text and no error or warning.
  • (b) children(node.id, node.basePath) renders correctly, but fails type-checking: TS2554: Expected 1 arguments, but got 2.

createCatalog passes A2UI's buildChild straight through as children (create-catalog.tsx:125), and buildChild is (id: string, basePath?: string) => ReactNode (a2ui-react/adapter.tsx:36). RendererProps.children (create-catalog.tsx:48) narrows it to (id: string). The built-in ChildList does pass node.basePath.

The repo's own renderers work around this with a cast, (children as any)(item.id, item.basePath): 58 call sites in 29 files, including every beautiful-chat/declarative-generative-ui/renderers.tsx in the showcase and the examples/integrations/*/declarative-generative-ui/renderers.tsx files.

Related, not part of this issue: props is typed as the schema's input (z.infer), so a ChildList prop is typed as string[] | { componentId, path }, while the renderer actually receives the resolved { id, basePath }[]. That is why the cast on props.items is needed. Happy to open a separate issue if that's useful.

Screenshots

No response

𝌚 CopilotKit Version

`@copilotkit/a2ui-renderer` 1.79.0 (`main` at c619451f); first seen on 1.67.1.

I have a fix with a test ready: type `children` as `(id: string, basePath?: string) => React.ReactNode` and document when to pass `basePath`. It's backward compatible, since existing one-argument calls still type-check. I'll open the PR and link it here.

📄 Logs (Optional)

Activity

  1. copilotkit-outpost-bot commented on Oct 13, 2026

    @copilotkit-outpost-bot

    ⚠️ This is an AI-generated response. We've escalated this to our engineering team — someone will follow up in this thread shortly.

    The type mismatch you've identified is real and the root cause is exactly what you traced: RendererProps.children in create-catalog.tsx:48 is typed as (id: string) => React.ReactNode, while the underlying buildChild that gets passed through at line 125 is (id: string, basePath?: string) => React.ReactNode. The built-in ChildList components in both catalog/basic and catalog/minimal already call buildChild(node.id, node.basePath) — so the implementation supports it, the public type just doesn't expose it.

    Your proposed fix (widening RendererProps.children to (id: string, basePath?: string) => React.ReactNode) is backward compatible and matches what the internals already do. The PR is the right path — engineering will verify and merge from there.


    🤖 Generated by CopilotKit AI Support · Documentation


    Was this helpful? React with 👍 or 👎

  2. added a commit that references this issue on Oct 15, 2026
    5bdb483
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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions