← Back to PRs

#23373: fix(bedrock): sanitize tool names to satisfy Bedrock Converse API constraint

by niceysam open 2026-02-22 08:03 View on GitHub →
app: web-ui agents size: S
Bedrock Converse API validates tool names against `[a-zA-Z0-9_-]+`. When a tool name contains a dot, colon, space or other special character, Bedrock returns: ``` 1 validation error detected: Value at 'messages.N.member.content.M.member.toolUse.name' failed to satisfy constraint: Member must satisfy regular expression pattern: [a-zA-Z0-9_-]+ ``` The error fires on every subsequent attempt using the cached history, putting the session in an infinite retry loop with no way to recover short of manually clearing the conversation. This adds `sanitizeToolNamesForBedrock()` alongside the existing `sanitizeToolsForGoogle()` pattern in `google.ts`. The sanitizer replaces any character outside `[a-zA-Z0-9_-]` with `_` and truncates names to 64 characters (Bedrock's hard limit). It is a no-op for non-Bedrock providers. The function is applied in both `attempt.ts` and `compact.ts` immediately after the Google sanitizer, so the tool list passed to pi-ai always has clean names before hitting the Bedrock Converse API. <!-- greptile_comment --> <h3>Greptile Summary</h3> This PR bundles three distinct changes: 1. **Bedrock tool name sanitization**: Adds `sanitizeToolNamesForBedrock()` to replace characters outside `[a-zA-Z0-9_-]` with underscores and truncate to 64 chars. Applied in both `attempt.ts` and `compact.ts` after the existing Google sanitizer. 2. **Cron session prompt mode fix**: Changes cron isolated sessions from "minimal" to "full" prompt mode, since they are independent agents needing the complete system prompt (including skills). References issue #19795. 3. **Empty text block filtering**: Filters empty text blocks in `extractText()` to prevent extra newlines in the web UI chat display. Includes tests. - The Bedrock sanitizer correctly handles tool **definitions** but does not sanitize tool names in **cached conversation history** (`toolUse.name` in assistant messages, `toolName` in toolResult messages). The Bedrock error path cited in the PR description (`messages[N].content[M].toolUse.name`) points to message history, so existing sessions with unsanitized tool names in their history may still trigger the validation error. - No unit tests were added for `sanitizeToolNamesForBedrock()` itself (the existing `google.e2e.test.ts` only covers the Google sanitizer). <h3>Confidence Score: 3/5</h3> - The PR fixes new sessions but may not fully resolve the cached history issue described in the PR motivation. - The Bedrock tool name sanitizer is correctly implemented for tool definitions and will prevent the issue for new sessions. However, the PR description states the error occurs at `messages[N].content[M].toolUse.name` (i.e., in cached history), and the fix does not sanitize tool names within existing conversation history messages. The cron prompt mode fix and empty text block filtering are clean and well-tested. No tests were added for the new `sanitizeToolNamesForBedrock()` function. - `src/agents/pi-embedded-runner/google.ts` — the sanitizer may need to also cover tool names in message history to fully address the described Bedrock validation error for existing sessions. <sub>Last reviewed commit: 8366c2c</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs