Skip to content

useTool run() overload error blames Promise<void> instead of the real branch-shape mismatch #617

Description

@zeke

Describe the Bug

useTool's TypeScript overload resolution falls over, with a genuinely confusing error, when a tool's run function returns different shapes from different branches. No output schema needs to be declared for this to happen.

Here's a real example, a commit_extraction tool:

useTool({
  name: 'commit_extraction',
  input: v.object({ /* ... */ }),
  async run({ data }) {
    if (alreadyDone) {
      return { output: { committed: false, alreadyCommitted: true } };
    }
    // ...
    return { output: { committed: true, factCount, summaryCount } };
  },
});

TypeScript's complaint is that Promise<...> isn't assignable to Promise<void>. That's misleading. There's no output schema anywhere in sight, and nothing about the error points at what's actually wrong: the two branches don't return the same shape.

Expected Behavior

One of two things would help here:

  • useTool infers the run return type as the union of both branches, so shapes that differ but are each individually valid still typecheck, or
  • if a single shape really is required, say so directly ("each branch of run must return the same output shape") instead of surfacing an unrelated Promise<void> mismatch.

Steps to Reproduce

  1. Write a tool whose run has two branches returning objects with different keys, like above.
  2. Run tsc (or wrangler types && tsc --noEmit).
  3. Watch the cascading overload error blame Promise<void>, with no mention of the actual shape mismatch.

Workaround

Made both branches return the same shape, including a boolean discriminant field (alreadyCommitted). The type error went away immediately.

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions