#7158·CopilotKit

Bug: input and header slots reject plain FCs (same defect as #7126)

Author: BenTaylorDevCreated Sep 15, 2026Updated Sep 16, 2026
Labelsbuggood first issue

Summary

#7126 fixed the chatView slot (PR #7156), but the same defect remains on two sibling slots. Any slot typed SlotValue<typeof X> where X carries namespace statics rejects a plain function component, even though the statics are never used at runtime.

Two slots are still affected:

Slot Declared as Where
input SlotValue<typeof CopilotChatInput> CopilotChatViewProps slot map, re-exposed on <CopilotChat>
header SlotValue<typeof CopilotModalHeader> CopilotSidebarView.tsx:24, CopilotPopupView.tsx:24

CopilotChatView, CopilotChatInput and CopilotModalHeader are the three slot targets in react-core/src/v2 that carry statics. Only the first is fixed.

Why it is wrong

renderSlot never reads the statics. It calls React.createElement(slot, props) (packages/react-core/src/v2/lib/slots.tsx). The type demands something the runtime does not use, which forces callers into Object.assign(MyInput, CopilotChatInput) or a cast — exactly the workaround #7126 reported.

Reproduction

Add this as a .test-d.ts under packages/react-core/src/v2/components/chat/__tests__/ and run nx run @copilotkit/react-core:check-types. Both assertions fail on current main.

typescript
import { expectTypeOf } from "vitest";
import type React from "react";
import type { CopilotChatProps } from "../CopilotChat";
import type { CopilotChatInputProps } from "../CopilotChatInput";
import type { CopilotModalHeaderProps } from "../CopilotModalHeader";
import type { CopilotSidebarViewProps } from "../CopilotSidebarView";

type InputSlot = NonNullable<CopilotChatProps["input"]>;
type HeaderSlot = NonNullable<CopilotSidebarViewProps["header"]>;

expectTypeOf<React.FC<CopilotChatInputProps>>().toExtend<InputSlot>();
expectTypeOf<React.FC<CopilotModalHeaderProps>>().toExtend<HeaderSlot>();

Suggested fix

Follow the shape PR #7156 landed — widen each declaration to the props-based form:

typescript
input?: SlotValue<React.ComponentType<CopilotChatInputProps>>;
header?: SlotValue<React.ComponentType<CopilotModalHeaderProps>>;

I verified on #7156 that this widening keeps prop checking intact: it still rejects a component demanding a prop the parent never passes, a component with a conflicting prop type, and a non-component object.

Do not fix it generically in SlotValue

This looks like it wants one fix in SlotValue itself, and #7156's first commit tried exactly that. It does not work. Adding ComponentType<ComponentProps<C>> as a union arm puts C in a circular inference position and degrades renderSlot's inference — I measured three new type errors in renderSlot.test.tsx (lines 93, 533, 574). #7156 narrowed to a single slot for this reason. Per-slot widening is the supported path unless someone finds a formulation that preserves inference.

Notes

  • Purely a type-level fix. No runtime change.
  • check-types enforces .test-d.ts files, so please add assertions alongside, as #7156 did.
  • The internal Object.assign workarounds in CopilotSidebar.tsx and CopilotPopup.tsx are now unnecessary for chatView and can be cleaned up separately.