Send Wahoo route file as data URI, not raw base64

Wahoo's POST /v1/routes expects route[file] as
'data:application/vnd.fit;base64,<base64>'. We were sending raw
base64, which Wahoo silently discarded — the route would appear in
the user's list with metadata (distance, ascent come from request
fields) but file.url stayed null and the Wahoo app rendered no track.
Confirmed by re-fetching route 50197876 via GET /v1/routes/:id.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Ullrich Schäfer 2026-05-01 10:29:43 +02:00
parent 2865ec748f
commit 5ea7342f4e
No known key found for this signature in database
GPG key ID: A32FF691A0F752D9
2 changed files with 8 additions and 3 deletions

View file

@ -114,7 +114,9 @@ describe("wahooProvider.pushRoute", () => {
expect(body.get("route[name]")).toBe("Test route");
expect(body.get("route[description]")).toBe("A test");
expect(body.get("route[start_lat]")).toBe("52.52");
expect(body.get("route[file]")).toBe(Buffer.from(fit).toString("base64"));
expect(body.get("route[file]")).toBe(
`data:application/vnd.fit;base64,${Buffer.from(fit).toString("base64")}`,
);
});
it.each([

View file

@ -181,7 +181,10 @@ export const wahooProvider: SyncProvider = {
},
async pushRoute(tokens: TokenSet, payload: PushRoutePayload): Promise<PushRouteResult> {
const fitBase64 = Buffer.from(payload.fit).toString("base64");
// Wahoo expects route[file] as a data URI, not raw base64. Sending plain
// base64 results in a route record where file.url is null and the Wahoo
// app shows the route in the list (with metadata) but renders no track.
const fitDataUri = `data:application/vnd.fit;base64,${Buffer.from(payload.fit).toString("base64")}`;
const body = new URLSearchParams({
"route[external_id]": payload.externalId,
"route[provider_updated_at]": payload.providerUpdatedAt.toISOString(),
@ -191,7 +194,7 @@ export const wahooProvider: SyncProvider = {
"route[start_lng]": payload.startLng.toString(),
"route[distance]": payload.distance.toString(),
"route[ascent]": payload.ascent.toString(),
"route[file]": fitBase64,
"route[file]": fitDataUri,
});
if (payload.description) body.set("route[description]", payload.description);
if (payload.filename) body.set("route[filename]", payload.filename);