I was experiencing repeated failures when creating AWS Bedrock Agent action groups using Claude 3.5 Sonnet as the foundation model. The CloudTrail error indicated an APISchemaException with tool name validation failures.
HttpVerb__ActionName__OperationId should match tool name regex for Claude 3.5 : ^[a-zA-Z0-9_-]{1,64}$
The action group was configured with an OpenAPI 3 specification containing four endpoints for a RESTful API service, deployed via Terraform using the aws_bedrockagent_agent_action_group
resource.
Initial Hypothesis: camelCase vs snake_case issue
Started by suspecting using snake_case in operationIds was the problem:
create_resource_plus_some_long_string
→ createResourcePlusSomeLongString
get_resource_by_id_plus_some_long_string
→ getResourceByIdPlusSomeLongString
update_resource_by_id_plus_some_long_string
→ updateResourceByIdPlusSomeLongString
delete_resource_by_id_plus_some_long_string
→ deleteResourceByIdPlusSomeLongString
Result: Still failed validation.
HttpVerb__ActionName__OperationId should match tool name regex for Claude 3.5 : ^[a-zA-Z0-9_-]{1,64}$
Second Attempt: Double Underscore matching expected format
Converted camelCase back to snake_case using double underscore approach following expected pattern:
createResourcePlusSomeLongString
→ POST__create__createResourcePlusSomeLongString
getResourceByIdPlusSomeLongString
→ GET__get__getResourceByIdPlusSomeLongString
updateResourceByIdPlusSomeLongString
→ POST__update__updateResourceByIdPlusSomeLongString
deleteResourceByIdPlusSomeLongString
→ DELETE__delete__deleteResourceByIdPlusSomeLongString
Result: Still failed validation.
Action name, operationId or http verb in openAPI schema should not have '__' for Claude3.5
Third Attempt: Converted operationIds back to camelCase only and shortened them.
I couldn’t figure out why my operationIds weren’t working. They were all following the expected format and regexp constraints. I confirmed this with the following terminal commands.
grep -o '"operationId": "[^"]*"' ./MY_FILE.json | while read line; do op=$(echo "$line" | sed 's/"operationId": "//; s/"//'); echo "$op: $(echo -n "$op" | wc -c) characters";
So I shortened them like so:
createResourcePlusSomeLongString
→ createResource
getResourceByIdPlusSomeLongString
→ getResource
updateResourceByIdPlusSomeLongString
→ updateResource
deleteResourceByIdPlusSomeLongString
→ deleteResource
Result: Still failed validation, but instead of four errors, I now only saw two.
What is going on? How do I fix this?
The issue isn’t just the regex ^[a-zA-Z0-9_-]{1,64}$
AWS Bedrock, when creating the aws_bedrockagent_agent_action_group
, appears to create the HttpVerb__ActionName__OperationId
operationId for you in the following manner.
Let’s take the following example:
resource "aws_bedrockagent_agent_action_group" "example" {
action_group_name = "lets_make_this_a_really_long_string_example"
…
}
{
"paths": {
"/v1/createResource": {
"get": {
"operationId": "createResource"
}
},
"/v1/getResourceById/{id}": {
"post": {
"operationId": "getResourceById"
}
},
"/v1/updateResourceById/{id}": {
"post": {
"operationId": "updateResourceById"
}
},
"/v1/deleteResourceById/{id}": {
"delete": {
"operationId": "deleteResourceById"
}
}
}
aws_bedrockagent_agent_action_group
appears to create the following “behind the scenes”.
HttpVerb__ActionName__OperationId
HttpVerb
comes from the json file verb
updateResourceById
the verb would be post
ActionName
is the action_group_name
in the AWS resource
lets_make_this_a_really_long_string_example
OperationId
is the operationId
in the json file
updateResourceById
would be the operationId
The final string that gets created behind the scenes is
POST_lets_make_this_a_really_long_string_example_updateResourceById
Character Count Analysis:
POST_lets_make_this_a_really_long_string_example_createResource
✅ (63 chars)GET_lets_make_this_a_really_long_string_example_getResourceById
✅ (63 chars)POST_lets_make_this_a_really_long_string_example_updateResourceById
❌ (67 chars)DELETE_lets_make_this_a_really_long_string_example_deleteResourceById
❌ (69 chars)Shorten all operationIds to be under the hidden 64 character limit
{
"paths": {
"/v1/createResource": {
"get": {
"operationId": "createResource"
}
},
"/v1/getResourceById/{id}": {
"post": {
"operationId": "getResource"
}
},
"/v1/updateResourceById/{id}": {
"post": {
"operationId": "updateResource"
}
},
"/v1/deleteResourceById/{id}": {
"delete": {
"operationId": "deleteResource"
}
}
}
Or make the action_group_name
shorter
resource "aws_bedrockagent_agent_action_group" "example" {
action_group_name = "a_short_action_group_name"
…
}
Action group creation succeeded after applying the hidden 64-character operationId limit for Claude 3.5 Sonnet.