halo-dev/halo · warning · Error
Please select two snapshots to compare
Error message
Please select two snapshots to compare
What it means
Thrown in the queryFn of SnapshotDiffContent.vue when snapshotNames.length is not exactly 2. The diff view needs exactly two snapshots (new + old) to compare. Notably, the `enabled` computed only checks !!snapshotNames?.length (truthy, i.e. >=1), so selecting exactly one snapshot enables the query but the queryFn throws this message — a guard/`enabled` mismatch that surfaces the error to the user via onError → Toast.
Source
Thrown at ui/console-src/components/snapshots/SnapshotDiffContent.vue:35
const props = withDefaults(
defineProps<{
cacheKey: string;
name: string;
snapshotNames?: string[];
getApi: (snapshotName: string) => Promise<ContentWrapper>;
}>(),
{
snapshotNames: () => [],
}
);
const { name, snapshotNames, cacheKey } = toRefs(props);
const { data: snapshot, isLoading } = useQuery({
queryKey: SNAPSHOT_DIFF_QUERY_KEY(cacheKey, name, snapshotNames),
queryFn: async () => {
if (snapshotNames.value?.length !== 2) {
throw new Error("Please select two snapshots to compare");
}
const newSnapshot = await props.getApi(snapshotNames.value[0]);
const oldSnapshot = await props.getApi(snapshotNames.value[1]);
return {
old: oldSnapshot,
new: newSnapshot,
};
},
onError(err) {
if (err instanceof Error) {
Toast.error(err.message);
}
},
enabled: computed(() => !!name.value && !!snapshotNames.value?.length),
});View on GitHub (pinned to d2f5165f9c)
Solutions
- Fix the `enabled` predicate to require exactly two snapshots so the query never runs in a throwing state: enabled = computed(() => !!name.value && snapshotNames.value?.length === 2).
- Ensure the parent only mounts/renders SnapshotDiffContent once two snapshots are chosen.
- If you intentionally keep the throw, suppress onError when length !== 2 to avoid duplicate UX feedback (the template already handles the empty/insufficient case visually).
- Add a type guard at the parent boundary so snapshotNames is typed as [string, string] only when two are selected.
Example fix
// before
enabled: computed(() => !!name.value && !!snapshotNames.value?.length),
queryFn: async () => {
if (snapshotNames.value?.length !== 2) {
throw new Error("Please select two snapshots to compare");
}
...
// after — align enabled with the queryFn's precondition
enabled: computed(() => !!name.value && snapshotNames.value?.length === 2), Defensive patterns
Strategy: validation
Validate before calling
// Require exactly two snapshots before the diff query can run
function twoSnapshotNames(names: string[] | undefined): [string, string] | null {
if (Array.isArray(names) && names.length === 2) return [names[0], names[1]];
return null;
}
// use in enabled + queryFn:
// enabled: computed(() => !!name.value && twoSnapshotNames(snapshotNames.value) !== null) Type guard
function hasTwoSnapshots(names: string[] | undefined): names is [string, string] {
return Array.isArray(names) && names.length === 2;
} Try / catch
onError(err) {
// Suppress the 'select two' message here — the template already shows select_two_tip
if (err instanceof Error && err.message !== "Please select two snapshots to compare") {
Toast.error(err.message);
}
} Prevention
- Make the `enabled` predicate require snapshotNames.length === 2, not merely truthy — this is the core fix that prevents the throw.
- Render SnapshotDiffContent only after two snapshots are chosen in the parent.
- Type the prop as a 2-tuple when two are selected to encode the invariant at the type level.
When it happens
Trigger: snapshotNames has length 1 (or >2): the enabled predicate is satisfied (truthy length) so useQuery runs, but queryFn asserts length === 2 and throws. Also reachable if the parent transiently passes a single-element array while the user is mid-selection, or if a snapshot list filter reduces the selection to one item reactively.
Common situations: User selects only one snapshot in the diff picker and the component renders; parent passes [onlyNew] before [old] is chosen; a watch updates snapshotNames to length 1 during reactivity churn; the diff UI is opened from a context that pre-selects a single snapshot. The onError shows 'Please select two snapshots to compare' as a toast even though the template's v-if (line 228) already shows a select-two tip — double feedback.
Related errors
- Please select a snapshot
- Attachment has no permalink
- Policy name is required
- File is required
- No permission to upload attachment
AI-assisted analysis of halo-dev/halo@d2f5165f9c (2026-08-14).
Data as JSON: /api/errors/bf2baa8b7a7910a5.
Report an issue: GitHub.