diff --git a/studio/frontend/src/features/training/components/hf-dataset-subset-split-selectors.tsx b/studio/frontend/src/features/training/components/hf-dataset-subset-split-selectors.tsx index d21fd55ff4..148341e4de 100644 --- a/studio/frontend/src/features/training/components/hf-dataset-subset-split-selectors.tsx +++ b/studio/frontend/src/features/training/components/hf-dataset-subset-split-selectors.tsx @@ -106,7 +106,7 @@ export function HfDatasetSubsetSplitSelectors({ : "rounded-lg border border-amber-200 bg-amber-50 px-3.5 py-2.5 text-xs text-amber-700 dark:border-amber-800 dark:bg-amber-950 dark:text-amber-400" } > - Could not fetch dataset splits: {error} + {error} )} diff --git a/studio/frontend/src/features/training/hooks/use-training-actions.ts b/studio/frontend/src/features/training/hooks/use-training-actions.ts index bfe035cf4a..1f3db35ce5 100644 --- a/studio/frontend/src/features/training/hooks/use-training-actions.ts +++ b/studio/frontend/src/features/training/hooks/use-training-actions.ts @@ -16,6 +16,19 @@ const ROLE_REMAP: Record> = { sharegpt: { user: "human", assistant: "gpt", system: "system" }, }; +function normalizeTrainingStartError(message: string): string { + const normalized = message.toLowerCase(); + const isLegacyDatasetScriptError = + normalized.includes("failed to check dataset format") && + normalized.includes("dataset scripts are no longer supported"); + + if (isLegacyDatasetScriptError) { + return "This Hub dataset relies on a legacy custom script and isn’t supported in this training flow."; + } + + return message; +} + export function useTrainingActions() { const isStarting = useTrainingRuntimeStore((state) => state.isStarting); const startError = useTrainingRuntimeStore((state) => state.startError); @@ -79,7 +92,9 @@ export function useTrainingActions() { const response = await startTraining(payload); if (response.status === "error") { - runtimeStore.setStartError(response.error || response.message); + const rawMessage = response.error || response.message; + const safeMessage = normalizeTrainingStartError(rawMessage); + runtimeStore.setStartError(safeMessage); runtimeStore.setStarting(false); return false; } @@ -88,9 +103,10 @@ export function useTrainingActions() { await syncTrainingRuntimeFromBackend(); return true; } catch (error) { - const message = + const rawMessage = error instanceof Error ? error.message : "Failed to start training"; - runtimeStore.setStartError(message); + const safeMessage = normalizeTrainingStartError(rawMessage); + runtimeStore.setStartError(safeMessage); runtimeStore.setStarting(false); return false; } diff --git a/studio/frontend/src/features/training/stores/training-runtime-store.ts b/studio/frontend/src/features/training/stores/training-runtime-store.ts index 7d5c86549b..41b0fcca07 100644 --- a/studio/frontend/src/features/training/stores/training-runtime-store.ts +++ b/studio/frontend/src/features/training/stores/training-runtime-store.ts @@ -187,7 +187,6 @@ export const useTrainingRuntimeStore = create()((set) => ( evalEnabled: payload.eval_enabled ?? state.evalEnabled, message: payload.message, error: payload.error, - startError: null, currentStep: typeof detailStep === "number" ? Math.max(detailStep, 0) : state.currentStep, totalSteps: diff --git a/studio/frontend/src/hooks/use-hf-dataset-splits.ts b/studio/frontend/src/hooks/use-hf-dataset-splits.ts index 7b8e4906ec..bc769b5b4b 100644 --- a/studio/frontend/src/hooks/use-hf-dataset-splits.ts +++ b/studio/frontend/src/hooks/use-hf-dataset-splits.ts @@ -35,6 +35,37 @@ export interface HfDatasetSplitsResult { const HF_SPLITS_API = "https://datasets-server.huggingface.co/splits"; +function normalizeDatasetSplitsError(message: string): string { + const normalized = message.toLowerCase(); + + // datasets-server returns technical script/runtime details for legacy datasets. + if ( + normalized.includes("dataset scripts are no longer supported") || + normalized.includes("runs arbitrary python code") || + normalized.includes(".py") + ) { + return "We can’t load subset/split options for this Hub dataset because it relies on a legacy custom script."; + } + + if ( + normalized.includes("unauthorized") || + normalized.includes("forbidden") || + normalized.includes("access token") || + normalized.includes("private") || + normalized.includes("gated") || + normalized.includes("401") || + normalized.includes("403") + ) { + return "Unable to load dataset splits. This dataset may be private or gated. Add a Hugging Face token with access and try again."; + } + + if (normalized.includes("not found") || normalized.includes("404")) { + return "Dataset not found. Check the dataset name and try again."; + } + + return "Unable to load dataset split options for this dataset."; +} + // --------------------------------------------------------------------------- // Hook // --------------------------------------------------------------------------- @@ -101,7 +132,18 @@ export function useHfDatasetSplits( }) .catch((err) => { if (!controller.signal.aborted) { - setError(err.message || "Failed to fetch dataset splits"); + const rawErrorMessage = + err instanceof Error + ? err.message + : typeof err === "string" + ? err + : "Failed to fetch dataset splits"; + console.warn("[useHfDatasetSplits] Failed to fetch dataset splits", { + datasetName, + message: rawErrorMessage, + error: err, + }); + setError(normalizeDatasetSplitsError(rawErrorMessage)); setEntries([]); } })