diff --git a/src/firmware/alerts/UnsupportedDfuHub.tsx b/src/firmware/alerts/UnsupportedDfuHub.tsx
new file mode 100644
index 00000000..23e4a910
--- /dev/null
+++ b/src/firmware/alerts/UnsupportedDfuHub.tsx
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: MIT
+// Copyright (c) 2025-2026 The Pybricks Authors
+
+import { Intent } from '@blueprintjs/core';
+import { Error } from '@blueprintjs/icons';
+import React from 'react';
+import type { CreateToast } from '../../toasterTypes';
+import { useI18n } from './i18n';
+
+const UnsupportedDfuHub: React.FunctionComponent = () => {
+ const i18n = useI18n();
+ return (
+ <>
+
{i18n.translate('unsupportedDfuHub.message')}
+ >
+ );
+};
+
+export const unsupportedDfuHub: CreateToast = (onAction) => ({
+ message: ,
+ icon: ,
+ intent: Intent.DANGER,
+ onDismiss: () => onAction('dismiss'),
+});
diff --git a/src/firmware/alerts/index.ts b/src/firmware/alerts/index.ts
index a6187418..1d922f91 100644
--- a/src/firmware/alerts/index.ts
+++ b/src/firmware/alerts/index.ts
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
-// Copyright (c) 2022-2025 The Pybricks Authors
+// Copyright (c) 2022-2026 The Pybricks Authors
import { dfuError } from './DfuError';
import { flashProgress } from './FlashProgress';
@@ -8,6 +8,7 @@ import { noDfuInterface } from './NoDfuInterface';
import { noWebHid } from './NoWebHid';
import { noWebUsb } from './NoWebUsb';
import { releaseButton } from './ReleaseButton';
+import { unsupportedDfuHub } from './UnsupportedDfuHub';
export default {
dfuError,
@@ -17,4 +18,5 @@ export default {
noWebHid,
noWebUsb,
releaseButton,
+ unsupportedDfuHub,
};
diff --git a/src/firmware/alerts/translations/en.json b/src/firmware/alerts/translations/en.json
index d43aa55d..d701b2b8 100644
--- a/src/firmware/alerts/translations/en.json
+++ b/src/firmware/alerts/translations/en.json
@@ -22,6 +22,9 @@
"installUsbDriverButton": "Install USB Driver",
"configureUdevRulesButton": "Configure udev rules"
},
+ "unsupportedDfuHub": {
+ "message": "This hub has different internal electronics and requires a different firmware. Pybricks does not support this yet. We are working on it!"
+ },
"noDfuInterface": {
"message": "This is very unusual. The USB device did not contain the expected interface."
},
diff --git a/src/firmware/sagas.ts b/src/firmware/sagas.ts
index 7ac4fea7..553166bf 100644
--- a/src/firmware/sagas.ts
+++ b/src/firmware/sagas.ts
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
-// Copyright (c) 2020-2025 The Pybricks Authors
+// Copyright (c) 2020-2026 The Pybricks Authors
import {
FirmwareReader,
@@ -754,6 +754,15 @@ function* handleFlashUsbDfu(action: ReturnType): Gen
return;
}
+ if (
+ device.productId === LegoUsbProductId.SpikePrimeBootloader &&
+ device.deviceVersionMajor !== 1
+ ) {
+ yield* put(alertsShowAlert('firmware', 'unsupportedDfuHub'));
+ yield* put(firmwareDidFailToFlashUsbDfu());
+ return;
+ }
+
const dfu = new WebDFU(
device,
// forceInterfacesName is needed to get the flash layout map