Skip to content

fix: recover failed and legacy Loom imports - #2331

Open
richiemcilroy wants to merge 26 commits into
mainfrom
codex/fix-loom-import-recovery
Open

richiemcilroy wants to merge 26 commits into
mainfrom
codex/fix-loom-import-recovery

Conversation

@richiemcilroy

@richiemcilroy richiemcilroy commented Sep 21, 2026 •

Copy link
Copy Markdown
Member

Loom imports could misclassify temporary source failures as private videos, lose streaming segment credentials, and reject recovery as duplicates. Share source resolution between the action and workflow, preserve access credentials, and retry temporary lookup failures durably. Failed imports retain their video IDs, ownership and placement, and reuse saved originals.

Recovery and safety

  • Reserve recovery capacity for failed imports even when startup confirmations remain unresolved.
  • Save workflow and worker dispatch receipts before requests. A timeout or missing run remains unconfirmed. Before retrying an accepted worker, verify the exact job and recording have reached the worker's failed state. A 404 is not proof of termination.
  • Validate live recordings and source mappings before operator completion. The operator queue now offers Reconcile deleted recordings, which requires source-list confirmation, locks the active request, and removes at most 100 inventory entries for absent videos per call. It preserves live recordings and source mappings, blocks live concurrent starts, honors expired startup reservations under the request lock, and never completes a migration or changes counts automatically.

10 GB imports

Support originals and processed output up to 10 GiB (10,737,418,240 bytes) with 64 MiB S3 multipart parts. Bind callbacks to the registered workflow attempt, recording, owner, organization, object key and upload ID. Conditional completion preserves existing objects. Retries reuse a saved output only after local full decode and remote identity, size and SHA-256 verification, without uploading it again. Preview failure is optional only on that verified reuse path. Failed uploads clean up incomplete reservations while retaining committed originals. Enforce the limit during direct and HLS downloads and before output upload.

Worker capability checks wait durably during rollout. Deploy the media-server change to all replicas before the web change. This PR does not establish production import completion, authorize deployment, or clear uncertain dispatches based on age.

Current-main integration

Integrated main at 0069c7e while preserving its cancellation, shutdown drain, temporary-file cleanup, processing heartbeat, ordinary parallel-download behavior and latest redacted verification/NVENC diagnostics. A bounded Loom import bypassed its byte limit when combined with the newer parallel-download path; bounded imports now use the size-checked path. The new regression test fails without the fix and passes with it. Stalled Loom recovery now checks the recorded workflow and worker state, claims the unchanged attempt and uses the shared receipt-saving startup path. Active, uncertain and legacy attempts remain held for reconciliation. Confirmed-inactive processing attempts can recover directly through the guarded startup path; active and uncertain checks rotate through the bounded queue so old holds cannot starve newer imports. Regression tests cover an eight-hold queue across two scans and preserving originals after rejected startup.

Verification

  • 663 focused web tests pass, including new video creation, share links/playback, desktop recording publication/finalization, multipart upload, and Loom recovery.
  • 290 media tests pass in isolated file runs, including real media processing, decode verification, storage upload, cancellation/lifecycle and parallel downloads.
  • Full root TypeScript build, route/workflow generation, scoped Biome and whitespace checks pass.
  • Sixteen database integration tests remain skipped because an isolated database fixture is unavailable. One opt-in long performance test is skipped. No database schema change.
  • Fresh exact-head CI and Greptile review are required for 9e7b49b.

Deploy the verified media image to every serving replica before releasing the web change. Production canary, customer source/mapping reconciliation and playback verification remain separate release gates.

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no new actionable defects were established.

Summary

This PR adds guarded recovery for failed and legacy Loom imports.

  • Loom imports keep the access details needed to fetch streamed video.
  • Failed Loom imports can restart on the same recording.
  • Loom imports can upload videos up to 10 GiB in large parts.
  • Migration operators can reconcile entries for deleted recordings.

The current code addresses the failures described in the earlier threads. Those threads were unnumbered, so they have no numbered entries above. This review inspected code and tests; it did not execute tests.

Reviews (12) · Last reviewed commit: "merge: preserve current media verificati..." · Reviewed by Greptile

@richiemcilroy richiemcilroy changed the title fix: retry failed Loom imports and temporary source failures fix: recover failed and legacy Loom imports Sep 21, 2026
@richiemcilroy
richiemcilroy marked this pull request as ready for review September 21, 2026 20:12
Comment thread apps/web/actions/loom.ts Outdated
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

@richiemcilroy

Copy link
Copy Markdown
Member Author

@greptileai review

@vercel

vercel Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
cap-status Skipped Skipped Oct 23, 2026 3:24pm UTC

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found 1 potential issue (1 medium).

Open in Capy

Comment thread apps/web/workflows/import-loom-video.ts
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found 1 potential issue (1 medium).

Open in Capy

uploadUpdatedAt: Date;
receipt: VideoMetadata["loomImportRun"];
}): Promise<FailedVideoProcessingRecoveryStatus> {
if (await isLoomImportRunning(receipt)) return "already-claimed";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale uncertain receipt permanently blocks Loom import recovery

Medium Severity

The new gate at line 149 treats an unqueryable run as live forever: isLoomImportRunning returns true on any getRun rejection and has no lease or expiry, and the PR's own test at loom-import-start.test.ts:199 pins that behaviour for a not-found error. Dispatch is unconfirmed in two reachable cases: startLoomImportWorkflow writes the pending receipt before calling world.queue, so a crash between those calls leaves pending with a never-dispatched runId, and a queue call failing with a non-rejection error (timeout, 5xx) records uncertain. If no run exists, getRun keeps rejecting on every fifteen-minute cron tick, the gate returns already-claimed, and updatedAt never advances so the row keeps matching the stale-upload query. Nothing clears loomImportRun once written, so the import is stranded at Importing from Loom with no error shown, and no path recovers it: manual retry returns a false already-processing because retry-processing.ts:85 uses the same helper, and re-importing returns already been imported at actions/loom.ts:461. Lines 196-198 compound this by keeping the claim on a non-retryable failure, moving the row to phase processing, which neither the pending nor failed query selects again. Bound the receipt check with a lease so recovery can reclaim an import whose run never materialised.

Open in Capy

@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

Open in Capy

Comment thread apps/web/app/api/webhooks/media-server/multipart/[action]/route.ts
@vercel
vercel Bot temporarily deployed to Preview – cap-status October 23, 2026 11:51 Inactive
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

Comment thread apps/web/lib/loom-import-upload.ts
@vercel
vercel Bot temporarily deployed to Preview – cap-status October 23, 2026 14:56 Inactive
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

Comment thread apps/web/lib/video-pipeline-recovery.ts
@vercel
vercel Bot temporarily deployed to Preview – cap-status October 23, 2026 15:02 Inactive
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

Comment thread apps/web/lib/video-processing-recovery.ts Outdated
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

@vercel
vercel Bot temporarily deployed to Preview – cap-status October 23, 2026 15:24 Inactive
@richiemcilroy

Copy link
Copy Markdown
Member Author

hey @greptileai, please re-review the PR

This branch was successfully deployed

2 active (1 outdated) and 1 inactive deployments
Preview – cap-web — 9e7b49ba Deployed Oct 23, 2026 by vercel[bot]
Preview – cap-status — 9e7b49ba Deployed Oct 23, 2026 by vercel[bot]
Preview — 1cc0e437 Deployed Sep 21, 2026 by vercel[bot]
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