Skip to content

fix: reject full-width space and tab in Bedrock document file names - #1677

Open
takke1986 wants to merge 2 commits into
aws-samples:mainfrom
takke1986:fix/safe-filename-fullwidth-space
Open

fix: reject full-width space and tab in Bedrock document file names#1677
takke1986 wants to merge 2 commits into
aws-samples:mainfrom
takke1986:fix/safe-filename-fullwidth-space

Conversation

@takke1986

Copy link
Copy Markdown
Contributor

Description of Changes

convertToSafeFilename sanitizes attachment file names for Bedrock's DocumentBlock.name, but the character class allowed \s:

nameWithoutExt.replace(/[^a-zA-Z0-9\s\-()[\]]/g, '_')

In JavaScript \s also matches U+3000 (ideographic space) and tabs, which Bedrock rejects. Kanji and kana were correctly replaced with _, so only whitespace characters slipped through the sanitizer. A file named テスト 資料.xlsx therefore failed with:

ValidationException: The document file name can only contain alphanumeric characters,
whitespace characters, hyphens, parentheses, and square brackets. ...

Full-width spaces are common in Japanese file names, so this is hit frequently. The reporter of #1671 measured about 19% of attached documents failing for this reason.

This PR:

  • allows only the ASCII space instead of \s
  • collapses consecutive spaces, which Bedrock also rejects
  • falls back to a placeholder when the sanitized name would be empty (name has a minimum length of 1)
  • applies the same fix to the AgentCore path in packages/web/src/utils/strandsUtils.ts, which had the identical \s in its character class

Not in scope: the file name length limit mentioned in the issue. The exact limit is not documented, so I left it out rather than guess. Happy to add it as a follow-up if you would like.

Compatibility: names that were already accepted are unchanged. Only names containing non-ASCII whitespace or consecutive spaces produce a different result, and those previously failed the API call outright.

Verified against the Bedrock API

I called bedrock-runtime:Converse in ap-northeast-1 with jp.anthropic.claude-haiku-4-5-20251001-v1:0, varying only document.name, to confirm that the names this function used to emit are actually rejected and the new ones are accepted.

document.name Produced by Result
test name (U+3000) before ValidationException
test_name_706fc6f2 after accepted
test name (two ASCII spaces) before ValidationException
test name_695fce01 after accepted
test\tname (tab) before ValidationException
_______9c852928 (all-Japanese name) after accepted
file_d41d8cd9 (empty-name fallback) after accepted
test name (single ASCII space) control accepted

This independently reproduces the table in #1671.

Checklist

  • Modified relevant documentation — n/a (internal utility; the JSDoc on the function was updated to state the actual constraint)
  • Verified operation in local environment
  • Executed npm run cdk:test — 45 tests / 15 snapshots passed, no snapshot differences

Also run:

  • npm -w packages/cdk test -- fileNameUtils15 passed (9 existing + 6 added)
  • npm run web:test — 278 passed
  • eslint and prettier --check clean on all changed files

Related Issues

convertToSafeFilename allowed \s through its character class, but in
JavaScript \s also matches U+3000 (ideographic space) and tabs, which
Bedrock's DocumentBlock.name rejects. Kanji and kana were replaced with
_, so only whitespace characters slipped past the sanitizer and the
attachment failed with ValidationException.

- Allow only the ASCII space instead of \s
- Collapse consecutive spaces, which Bedrock also rejects
- Fall back to a placeholder when the sanitized name would be empty,
  since name has a minimum length of 1
- Apply the same fix to the AgentCore path in strandsUtils.ts

Verified against bedrock-runtime:Converse in ap-northeast-1: the names
this function used to emit are rejected and the new ones are accepted.
A reviewer pointed out on aws-samples#1671 that the length limit I left out of scope
is documented after all. DocumentBlock.name carries "Minimum length of 1.
Maximum length of 200." on the same API reference page that documents the
whitespace rule this PR already fixes, so treating it as unspecified was
my mistake.

Both call sites now truncate. Where a hash suffix is added it is the hash
that keeps two different names apart, so the base name is trimmed to make
room rather than the suffix being dropped. Truncation can also leave a
trailing space, which is not rejected but reads as an accident in the name
the model is shown, so it is removed.

Verified against bedrock-runtime:Converse in us-east-1: a 200-character
name is accepted, a 201-character one is rejected with the message quoted
on the issue.
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

Successfully merging this pull request may close these issues.

1 participant