You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
useObjectChat's returned setMessages is typed (messages: unknown[]) to void — contravariantly incompatible with the SDK's, and only the chatResult as any at :683 hides it #8342
Found while widening AnyPart.state for objectui#8214. Filed unassigned and NOT fixed there — that card's ruling is a local widening in mapMessages.ts and explicitly says not to widen the PR to chase whatever the second cast is hiding.
Filed by the objectui#8214 dev, Claude Code session session_01YBWFb5YgMU5dw8p2VKj16S. (Attribution is stated here in prose: the trailing rule-line footer block was stripped from this body by the platform on creation, so it is not a durable place to put it.)
Spelling note: generic type arguments are written as WORDS below, because GitHub's body sanitizer eats tag-shaped fragments, backticks and fences included.
What
packages/plugin-chatbot/src/useObjectChat.ts:683 destructures the useChat() result through chatResult as any. objectui#8214 named that cast load-bearing and asked what it is actually holding up. Measured: with objectui#8214's widen applied, removing the cast leaves exactly one diagnostic, and it is not about the mapper at all.
src/useObjectChat.ts(803,7): error TS2322: Type '(messages: UIMessage of unknown, UIDataTypes, UITools array
| ((messages: UIMessage array) to UIMessage array)) to void' is not assignable to type
'(messages: unknown[]) to void'.
Types of parameters 'messages' and 'messages' are incompatible.
Type 'unknown[]' is not assignable to type 'UIMessage array | ((messages: UIMessage array) to UIMessage array)'.
Type 'unknown' is not assignable to type 'UIMessage of unknown, UIDataTypes, UITools'.
(Arrow spelled as the word "to" above for the same sanitizer reason.)
The hook returns setMessages declared as taking messages: unknown[]. Parameters are contravariant, so a function that accepts only UIMessage[] is not assignable to one advertised as accepting any unknown[]. The declared type promises callers something the underlying function cannot do.
Reachability
No runtime effect today: the value passed through is the SDK's own setMessages and every in-repo caller happens to hand it real messages. The cost is the same shape objectui#8214 was graded on — the published surface tells a consumer they may pass an arbitrary unknown[], and the only reason nothing breaks is that nobody has taken the type at its word. A consumer who does gets a runtime failure the compiler said was fine.
Instrument: pnpm --filter @object-ui/plugin-chatbot type-check (tsc --noEmit && tsc -p tsconfig.test.json). Vitest cannot see this — it transpiles types away.
With the cast in place: exit 0. With } = chatResult as any; changed to } = chatResult;: exit 2, one diagnostic, the TS2322 above. The mutation was proved on disk and restored by state (git diff HEAD empty, git hash-object equal to git rev-parse HEAD:PATH again).
Options, not a ruling
A. Type the hook's returned setMessages against what it actually is (the SDK's signature, or a narrowed alias the package owns), and drop the cast. Strictest; ties one more return member to the pinned @ai-sdk/react version, which is the same decision objectui#8214 deliberately declined to make on its parameter type. Probably wants the same eye.
B. Keep the returned member deliberately loose but make it honest — accept unknown[] and validate/narrow inside the hook before handing it to the SDK, so the promise on the surface is one the implementation actually keeps.
C. Leave the cast and document it. Rejected by the same rule that rejected it on objectui#8214 (AGENTS.md #0.1): a documented cast fossilizes the wrong shape.
Whoever takes this should re-measure before acting — the diagnostic count is measured on top of PR #8341 and may read differently once that lands or if the SDK moves.
Related: objectui#8214 (where the cast was named and this half was deliberately left alone), objectui#4424 (the previous cast removed from this same hook's return path), objectui#4399.
Found while widening
AnyPart.statefor objectui#8214. Filed unassigned and NOT fixed there — that card's ruling is a local widening inmapMessages.tsand explicitly says not to widen the PR to chase whatever the second cast is hiding.Filed by the objectui#8214 dev, Claude Code session
session_01YBWFb5YgMU5dw8p2VKj16S. (Attribution is stated here in prose: the trailing rule-line footer block was stripped from this body by the platform on creation, so it is not a durable place to put it.)Spelling note: generic type arguments are written as WORDS below, because GitHub's body sanitizer eats tag-shaped fragments, backticks and fences included.
What
packages/plugin-chatbot/src/useObjectChat.ts:683destructures theuseChat()result throughchatResult as any. objectui#8214 named that cast load-bearing and asked what it is actually holding up. Measured: with objectui#8214's widen applied, removing the cast leaves exactly one diagnostic, and it is not about the mapper at all.(Arrow spelled as the word "to" above for the same sanitizer reason.)
The hook returns
setMessagesdeclared as takingmessages: unknown[]. Parameters are contravariant, so a function that accepts onlyUIMessage[]is not assignable to one advertised as accepting anyunknown[]. The declared type promises callers something the underlying function cannot do.Reachability
No runtime effect today: the value passed through is the SDK's own
setMessagesand every in-repo caller happens to hand it real messages. The cost is the same shape objectui#8214 was graded on — the published surface tells a consumer they may pass an arbitraryunknown[], and the only reason nothing breaks is that nobody has taken the type at its word. A consumer who does gets a runtime failure the compiler said was fine.Measured
dacb98f3bplus objectui#8214's widen (PR fix(plugin-chatbot): accept the AI SDK's UIMessage in the exported mappers #8341).pnpm --filter @object-ui/plugin-chatbot type-check(tsc --noEmit && tsc -p tsconfig.test.json). Vitest cannot see this — it transpiles types away.} = chatResult as any;changed to} = chatResult;: exit 2, one diagnostic, the TS2322 above. The mutation was proved on disk and restored by state (git diff HEADempty,git hash-objectequal togit rev-parse HEAD:PATHagain).Options, not a ruling
setMessagesagainst what it actually is (the SDK's signature, or a narrowed alias the package owns), and drop the cast. Strictest; ties one more return member to the pinned@ai-sdk/reactversion, which is the same decision objectui#8214 deliberately declined to make on its parameter type. Probably wants the same eye.unknown[]and validate/narrow inside the hook before handing it to the SDK, so the promise on the surface is one the implementation actually keeps.Whoever takes this should re-measure before acting — the diagnostic count is measured on top of PR #8341 and may read differently once that lands or if the SDK moves.
Related: objectui#8214 (where the cast was named and this half was deliberately left alone), objectui#4424 (the previous cast removed from this same hook's return path), objectui#4399.