Skip to content

finding(plugin-chatbot): useObjectChat's second cast, useChat({...} as any), is DEAD — measured, removing it leaves zero diagnostics #8378

Description

@os-justin

Found while fixing objectui#8342 (PR #8377). Filed unassigned and NOT fixed there — #8342's scope is the chatResult as any at the destructure and the return member it was hiding; this is a different cast on a different line, and the bounded-in-place exemption does not apply because its shape was not pinned in advance.

Filed by the objectui#8342 dev, Claude Code session session_01YBWFb5YgMU5dw8p2VKj16S.

Spelling note: generic type arguments are written as WORDS where they appear, because GitHub's body sanitizer eats tag-shaped fragments.

What

packages/plugin-chatbot/src/useObjectChat.ts had TWO as any casts on the useChat seam. objectui#8342 named and removed one of them (the destructure). The other is on the ARGUMENT:

  const chatResult = useChat({
    transport,
    messages: isApiMode && aiInitialMessages.length > 0 ? (aiInitialMessages as any) : undefined,
    onError: ...,
  } as any);          <-- this one, :735 after PR #8377

Measured on PR #8377's head (5f9345554, worktree at /home/user/objectui-issue-8342), with the dependency closure built first:

  • anchor before mutation: 1 hit for the line } as any);; after: 0 hits, and git hash-object differed from git rev-parse HEAD:PATH, so the mutation reached disk.
  • pnpm --filter @object-ui/plugin-chatbot exec tsc --noEmit (run as ./node_modules/.bin/tsc --noEmit in the package): exit 0, zero error TS lines.
  • Restored by state: git diff HEAD empty and the blob equal to HEAD:PATH again.

So this cast is holding nothing up in the main program. It is not the other half of #8342 — it is dead.

Why it is worth a card rather than a shrug

AGENTS.md #0.1: a cast tells the compiler to stop looking. A DEAD one is worse than a live one, because it silently acquires new hiding power the next time the options object or the SDK's UseChatOptions moves — nobody re-measures a cast that has been there for a year. #8342's whole grading was about exactly this: a suppression nobody had asked what it was suppressing.

There is also a second-order effect worth checking as part of the work: with the argument cast in place, useChat's generic parameter cannot be inferred from the options and falls back to its default. Removing the cast lets inference run. It stayed green here, but that is a behaviour of the type system, not a no-op, and whoever takes this should say which instantiation results.

Not yet measured — do not assume

Only tsc --noEmit (the main program) was run against the mutation. Before removing the cast, the taker must also run:

  • tsc -p tsconfig.test.json (the test program — objectui#8342's leg 4 showed a change can be green in the main program and red only here);
  • pnpm --filter @object-ui/plugin-chatbot test;
  • pnpm --filter '...@object-ui/plugin-chatbot' type-check (7 dependent projects).

The nested (aiInitialMessages as any) on the messages property is a THIRD cast on the same call and is deliberately out of this card's scope — measure it separately, since it may be the reason the outer one appears dead.

Related: objectui#8342 (the cast that was live), objectui#8214, objectui#4424, objectui#4399.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions