From 935efedae01a4ca6bc95657e952e26f9c0282855 Mon Sep 17 00:00:00 2001 From: Jamie Pine Date: Sat, 25 Apr 2026 02:12:00 -0700 Subject: [PATCH] fix(stories): round split_time_ms before posting handleSplit was sending currentTimeMs - item.start_time_ms straight to the backend, which rejects it because StoryItemSplit.split_time_ms is typed as int and the playhead's currentTimeMs is a float (it's driven from HTMLAudioElement.currentTime, which carries sub-millisecond precision). Pydantic surfaced the mismatch as "Input should be a valid integer, got a number with a fractional part" and the toast read "Failed to split clip". Math.round at the call site, matching what the trim and move handlers already do. --- app/src/components/StoriesTab/StoryTrackEditor.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/components/StoriesTab/StoryTrackEditor.tsx b/app/src/components/StoriesTab/StoryTrackEditor.tsx index 0f4ba281..0ef3e981 100644 --- a/app/src/components/StoriesTab/StoryTrackEditor.tsx +++ b/app/src/components/StoriesTab/StoryTrackEditor.tsx @@ -587,7 +587,10 @@ export function StoryTrackEditor({ storyId, items }: StoryTrackEditorProps) { const item = items.find((i) => i.id === selectedClipId); if (!item) return; - const splitTimeMs = currentTimeMs - item.start_time_ms; + // currentTimeMs is driven by audio playback and arrives as a float; + // the backend's StoryItemSplit.split_time_ms is `int`, so round before + // sending or pydantic rejects the request. + const splitTimeMs = Math.round(currentTimeMs - item.start_time_ms); const effectiveDuration = getEffectiveDuration(item); if (splitTimeMs <= 0 || splitTimeMs >= effectiveDuration) {