Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Types] Error: Property 'text' does not exist on type 'ContentBlock'. #432

Open
davidstackio opened this issue May 31, 2024 · 6 comments
Open
Assignees

Comments

@davidstackio
Copy link

After updating to v0.22.0 from v0.20.9, I'm getting a type error on the last line of this block (text = msg.content[0].text;):

const msg = await anthropic.messages.create({
      model: "claude-3-opus-20240229",
      max_tokens: maxOutputTokens,
      temperature: 0.9,
      messages: [
        {
          role: "user",
          content: [
            {
              type: "text",
              text: prompt,
            },
          ],
        },
      ],
    });
    text = msg.content[0].text;

The type error is:

Property 'text' does not exist on type 'ContentBlock'.
  Property 'text' does not exist on type 'ToolUseBlock'.ts(2339)

When logging the message content, it does not appear to have changed, so I'm guessing this is just a type bug that needs fixed. My code works as expected when adding the // @ts-ignore comment above the problem line, which is my current workaround.

@olu-an
Copy link

olu-an commented May 31, 2024

cc @rattrayalex to see if it's an SDK issue

@bcherny
Copy link

bcherny commented Jun 19, 2024

It seems like this is an intentional change introduced in #429.

Prior to that PR, response messages were always of type text (ie. content generated by Claude). After the PR, responses can be either text(as before) or tool_use, meaning Claude invoked an external tool.

To fix the TypeScript error, you'll want to refine Claude's response, to explicitly check which type of response it is. It is no longer safe to assume the response is always text:

const response = msg.content[0];
switch (response.type) {
  case 'text':
    const text = response.text;
    // ...
  case 'tool_use':
    // ...
}

You can also use if or any other conditional check to refine the response.

Alternatively, if you know the response will always be content (ie. you did not configure a tool), you can use a type assertion. Though, note this is not as typesafe as an explicit if:

const text = (msg.content[0] as Anthropic.TextBlock).text;

See https://docs.anthropic.com/en/docs/build-with-claude/tool-use#chain-of-thought


For Anthropic folks -- there's a minor improvement you might consider to make the SDK a bit easier to use: add an overloaded type signature to create, so that it returns content of type ContentBlock if tool is configured, and otherwise returns content of type TextBlock. That would make it so the PR above doesn't break builds for folks that don't use tools.

@rattrayalex
Copy link
Collaborator

Hey, sorry for the delay at taking a look here. @bcherny is correct that this is intentional, but I also quite like the overload idea. No guarantees we'll be able to get to it soon, but I'll shop it around.

@rattrayalex
Copy link
Collaborator

rattrayalex commented Jun 20, 2024

I'll leave this issue open, even though it is indeed Working As Intended, because I'd really like to improve the developer experience here.

@jonnicholson94
Copy link

Just to comment, I had this problem this morning - didn't find the docs too clear, and a bit hacky (in my opinion) to have to explicitly declare the type like that when it'll always be 'text' for my example. A solution would be great!

@kmankan
Copy link

kmankan commented Nov 16, 2024

is there a better solution to this yet? I was running into this for a while and couldn't really figure out from the type error what the problem was or how to address it. this thread was very useful though.

Also, amusingly, claude-3.5-sonnet doesn't easily immediately know how to fix this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants