Memory Upload Stuck Showing "Processing..." Indefinitely
Metadata
- Date:
2026-05-09 - Status:
investigating - Severity:
high - Related issue/ticket:
memory-upload-stuck - Owner:
Memory Upload & Enrichment Flow
About
Overview: - User uploads a memory through the app - UI shows "Processing..." indefinitely and never completes - The memory appears in the feed with processing_status showing as "pending" even after upload completes
Technical Questions: - Is the video endpoint checking segment processing_status before returning a presigned URL? - Does the frontend retry polling the video endpoint if processing_status is pending? - Is there a missing auto-refresh mechanism in the memory viewer modal?
Resources: - Frontend: main/app/lib/api/memory/video.ts (POST /memories/video) - Backend: main/server/api/memories/video/app.py (video endpoint) - Frontend UI: main/app/components/memory/memory-viewer-modal.tsx (ProcessingOverlay) - Feed: main/server/api/memories/feed/app.py (determines processing_status)
Steps to cause failure
flowchart LR
A[User uploads memory] --> B[startMemoryUpload returns memory_id]
B --> C[uploadMemoryPart streams S3 parts]
C --> D[completeMemoryUpload marks upload done]
D --> E[User navigates to memory]
E --> F[getMemoryVideo called once]
F --> G["Video endpoint returns presigned_url (no processing_status in response)"]
G --> H["Frontend assumes video is complete, caches result"]
H --> I["Processing still pending in backend"]
I --> J["ProcessingOverlay shows indefinitely"] System
flowchart TD
Mobile[MemoryViewerModal] --> Video["getMemoryVideo (POST /memories/video)"]
Video --> VidAPI["Video Lambda (MemoriesVideoFunction)"]
VidAPI --> DB["PostgreSQL segment lookup"]
DB --> S3Frames["S3 frame/audio download"]
S3Frames --> FFmpeg["FFmpeg encode"]
FFmpeg --> S3Upload["S3 upload MP4"]
S3Upload --> PresignedURL["Generate presigned URL"]
PresignedURL --> Response["Return to frontend"]
Response --> Cache["Video cache stores result"]
Cache --> UI["Renders 'Processing...' if status is pending"]
Feed["Feed API provides processing_status"]
Feed --> DB Notes: - The video endpoint finds the segment but never checks or returns its processing_status - The frontend video API response type includes optional processing_status field but video endpoint never returns it - Frontend relies on polling the video endpoint, but if the initial call succeeds (segment exists), the result is cached and never re-polled - When a segment is still pending enrichment, the video endpoint returns frames that exist BUT the UI still shows "Processing..." because feed shows "pending" status
Reproduction Details
- Create a memory by uploading audio/video through the mobile app
- Wait for
completeMemoryUploadto return successfully - Navigate to memory viewer (memory-viewer-modal)
- Call
getMemoryVideo({ memory_id })while backend is still enriching the segment - Observe: getMemoryVideo returns
presigned_urlbutprocessing_statusis undefined - Observe: Frontend caches the response and never re-polls
- Observe: ProcessingOverlay stays visible indefinitely
Reproduction test (unit preferred): main/app/__tests__/memory-viewer-modal.test.tsx - add test for polling when status is pending
Notes for PR
Root cause: The video endpoint (main/server/api/memories/video/app.py) returns a presigned URL without checking or including the segment's processing_status. The frontend's getMemoryVideo response type includes optional processing_status but the backend never populates it, so the frontend cannot determine if the video is still being processed.
Additionally, the frontend caches the video response on first successful fetch, preventing any retry polling when the status is initially pending.
Fix required: 1. Video endpoint must check segment.processing_status and return it in the response 2. Video endpoint should return "pending" processing_status if segment is not complete yet 3. Frontend should continue polling if status is "pending" (poll with exponential backoff or interval) 4. Video cache must invalidate if processing_status is pending (do not cache pending state)
Audit Log
| ID | Action | Note | Context |
|---|---|---|---|
| 1 | Create audit log | Initialize bug investigation | issue reported |
| 2 | Code review | Found video endpoint missing processing_status check | main/server/api/memories/video/app.py:194-199 |
| 3 | Code review | Found frontend not polling if status pending | main/app/lib/video/video-prefetch-cache.ts:19-31 |
Verification
- [ ] Reproduced failure before fix
- [ ] Reproduction test fails before fix
- [ ] Root cause identified with evidence
- [ ] Fix applied at source (no workaround-only patch)
- [ ] Reproduction test passes after fix
- [ ] Reproduction path now passes
- [ ] Regression test added/updated (or
N/Awith reason) - [ ] Verified no duplicate solved-bug log exists for same root cause