fix(files): resolve chat uploads whose names are not in VFS form - #8566
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
|
There was a problem hiding this comment.
All reported issues were addressed across 4 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
There was a problem hiding this comment.
1 issue found across 4 files
Confidence score: 3/5
- In
apps/sim/lib/uploads/contexts/workspace/workspace-file-manager.ts, distinct uploads can resolve to the same canonical VFS path, causing an older upload notice to point to the newest file. Use the same normalization when allocating chat display names and enforcing uniqueness.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="apps/sim/lib/uploads/contexts/workspace/workspace-file-manager.ts">
<violation number="1" location="apps/sim/lib/uploads/contexts/workspace/workspace-file-manager.ts:1611">
P1: This normalized match can make two distinct uploads share one canonical VFS path and redirect an older upload notice to the newest file. Allocate chat display names and enforce uniqueness using the same normalized display key before resolving them here.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
Summary
uploads/<name>— not by the path the upload notice prints, and not by the raw name. The agent gets "File not found" fromfiles read,run_codeinput mounts, and every otheruploads/read, then gives up on the attachmentScreenshot <date> at <time> AM.png— macOS puts U+202F before AM/PM), along with names that contain doubled spaces, decomposed (NFD) accents, or control characters. Over the last two weeks that was roughly one in five Chat uploadsencodeVfsSegment(name), which normalizes the name (NFC, trim, strip control characters, collapse every whitespace run to one space).parseChatUploadReferencedecodes back to that normalized form, butgetChatUploadByNamecompared it to the raw storeddisplay_namewith=. Workspace files never hit this because the listing fallback compares normalized forms on both sides. Chat uploads are excluded from that listing on purpose, so their only path was the exact match. The bug has been there since theuploads/namespace landed in feat(mothership): v1.0.0 #8208getChatUploadByNamenow matches in the stored name's display form, entirely in SQL, and still returns one row (limit(1), newest first). The stored name is NFC-composed and its control characters are stripped. It is then matched againstdisplaySegmentPattern(name), a new anchored regex inlib/vfs/path.ts. The pattern takes the requested words, regex-escaped, in order, separated by whitespace runs, and allows whitespace around them. Its whitespace class is the same constant VFS encoding uses to collapse whitespace, so the two cannot drift. Scope predicates are unchanged (workspace,context = 'mothership', chat, live)Behavior changes
uploads/<name>reference resolved only when the stored name was already normalized. Now it resolves whenever the stored name normalizes to the same display name, which is the path the VFS shows the modeluploads/references are untouchedType of Change
Testing
file-names.integration.tsagainst real Postgres (bun run test:integration):a_bdoes not matchaxb,notes.pngdoes not matchmy notes.png.bak), and%and\in names still resolveworkspace-file-reference.test.ts: dropped the assertions that pinned the oldor(eq(displayName…))query shape andlimit(1). Behavior is now covered by the real-Postgres testbun run lint,bun run type-check(apps/sim),bun run check:audits,docs-manifest:check,check-block-registry, rootbun run testChecklist
test-auditauthoring gate)