From 9aaa17c898d214a80bebed1260e3d4a01ab521a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ullrich=20Sch=C3=A4fer?= Date: Sat, 4 Apr 2026 11:41:28 +0100 Subject: [PATCH] Fix Wahoo import crash for workouts without FIT files Some Wahoo workouts (indoor, manual entries) don't have a FIT file URL. Both the manual import action and webhook handler called downloadFile unconditionally, throwing "No file URL for workout". Now skips the download and creates the activity without GPX when no file is available. Co-Authored-By: Claude Opus 4.6 (1M context) --- apps/journal/app/routes/api.sync.webhook.$provider.ts | 9 ++++++--- apps/journal/app/routes/sync.import.$provider.tsx | 7 +++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/journal/app/routes/api.sync.webhook.$provider.ts b/apps/journal/app/routes/api.sync.webhook.$provider.ts index fdf1b2e..adbc4d3 100644 --- a/apps/journal/app/routes/api.sync.webhook.$provider.ts +++ b/apps/journal/app/routes/api.sync.webhook.$provider.ts @@ -44,10 +44,13 @@ export async function action({ params, request }: Route.ActionArgs) { await updateTokens(connection.id, tokens); } - // Download and convert + // Download and convert (if file available) const workout = { id: event.workoutId, name: "", type: "", startedAt: "", duration: null, distance: null, fileUrl: event.fileUrl }; - const fileBuffer = await provider.downloadFile(tokens, workout); - const gpx = await provider.convertToGpx(fileBuffer); + let gpx: string | null = null; + if (workout.fileUrl) { + const fileBuffer = await provider.downloadFile(tokens, workout); + gpx = await provider.convertToGpx(fileBuffer); + } // Create activity const activityId = await createActivity(connection.userId, { diff --git a/apps/journal/app/routes/sync.import.$provider.tsx b/apps/journal/app/routes/sync.import.$provider.tsx index 7bf6f66..5d01e62 100644 --- a/apps/journal/app/routes/sync.import.$provider.tsx +++ b/apps/journal/app/routes/sync.import.$provider.tsx @@ -86,8 +86,11 @@ export async function action({ params, request }: Route.ActionArgs) { fileUrl: fileUrl || undefined, }; - const fileBuffer = await provider.downloadFile(tokens, workout); - const gpx = await provider.convertToGpx(fileBuffer); + let gpx: string | null = null; + if (workout.fileUrl) { + const fileBuffer = await provider.downloadFile(tokens, workout); + gpx = await provider.convertToGpx(fileBuffer); + } const activityId = await createActivity(user.id, { name: workoutName || `${provider.name} workout`,