fix(onboarding): add explicit EFI loader path for flash entry#1926
fix(onboarding): add explicit EFI loader path for flash entry#1926Ajit-Mehrotra merged 6 commits intomainfrom
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds EFI boot loader path to efibootmgr calls, replaces raw device mapping with resolved boot-device resolution and richer diagnostic logging during internal-boot creation, and changes onboarding UI disk selection to prefer Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant OnboardingService
participant DisksService
participant Emcmd
participant Efibootmgr
participant StateStore
Client->>OnboardingService: createInternalBootPool(input)
OnboardingService->>StateStore: loadStateFiles(var/devs/disks)
OnboardingService->>DisksService: getAssignableDisks()
OnboardingService->>OnboardingService: resolveRequestedBootDevices(assignableDisks, requested)
OnboardingService->>Emcmd: runStep("bios-update"/others)
Emcmd-->>OnboardingService: result / error (logged)
OnboardingService->>Efibootmgr: create flash entry (-l '\EFI\BOOT\BOOTX64.EFI')
Efibootmgr-->>OnboardingService: success / failure (logged)
OnboardingService->>StateStore: invalidateInternalBootState()
OnboardingService-->>Client: result (with diagnostics)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1926 +/- ##
==========================================
+ Coverage 51.66% 51.71% +0.04%
==========================================
Files 1026 1026
Lines 70932 70989 +57
Branches 7841 7849 +8
==========================================
+ Hits 36650 36713 +63
+ Misses 34160 34154 -6
Partials 122 122 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@web/src/components/Onboarding/steps/OnboardingInternalBootStep.vue`:
- Around line 172-173: The backend cannot resolve serial numbers because
resolveBootDevicePath() only looks up keys in devsById (populated by
getDeviceMapFromEmhttpState() using disk.id), while the frontend may send
serialNum in the devices array to createInternalBootPool; update the backend
mapping logic to also index devices by serial number (add serial -> devicePath
entries when building devsById in getDeviceMapFromEmhttpState or add a parallel
map) so resolveBootDevicePath() can resolve either disk.id or serialNum, or
alternatively change the frontend to send only disk.id (ensure
createInternalBootPool is called with the id present in devsById).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 0a4412cc-cfd5-4667-a455-373eb1cc8046
📒 Files selected for processing (2)
web/src/components/Onboarding/steps/OnboardingInternalBootStep.vueweb/src/components/Onboarding/steps/OnboardingSummaryStep.vue
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@api/src/unraid-api/graph/resolvers/onboarding/onboarding-internal-boot.service.ts`:
- Around line 262-263: The code is appending full emhttp.devices dumps
(rawDevicesText and parsedDevicesText) to the response output array in
createInternalBootPool; remove those pushes (output.push(`emhttp.devices raw:
${rawDevicesText}`) and the parsedDevicesText push) so sensitive hardware
identifiers aren't returned, and instead, if needed, add a brief redacted
summary (e.g., counts or masked IDs) to output or rely on logger.debug
(`this.logger.debug(...)`) for full details; ensure rawDevicesText and
parsedDevicesText remain only in logs and not included in the API response.
- Around line 345-349: In createInternalBootPool, when a bootDevice input fails
to resolve (where resolved is falsy and you currently call this.logger.warn with
the message including bootDevice), set the hadFailures flag to true before
continuing so the overall result reflects the failure; update the unresolved
branch (the block that logs `createInternalBootPool unable to resolve boot
device input='${bootDevice}'`) to assign hadFailures = true and then continue.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 418275cc-019f-486e-9923-76286d2fe138
📒 Files selected for processing (1)
api/src/unraid-api/graph/resolvers/onboarding/onboarding-internal-boot.service.ts
api/src/unraid-api/graph/resolvers/onboarding/onboarding-internal-boot.service.ts
Outdated
Show resolved
Hide resolved
| if (!resolved) { | ||
| this.logger.warn( | ||
| `createInternalBootPool unable to resolve boot device input='${bootDevice}'` | ||
| ); | ||
| continue; |
There was a problem hiding this comment.
Mark unresolved boot-device resolution as a BIOS update failure.
Line 345-Line 349 currently logs and skips unresolved inputs, but hadFailures remains unchanged. This can return a successful result even when a requested boot entry was not created.
Proposed fix
for (const bootDevice of devices) {
const resolved = this.resolveBootDevicePath(bootDevice, devsById);
if (!resolved) {
this.logger.warn(
`createInternalBootPool unable to resolve boot device input='${bootDevice}'`
);
+ output.push(
+ `efibootmgr skipped unresolved boot device input='${bootDevice}'`
+ );
+ hadFailures = true;
continue;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| if (!resolved) { | |
| this.logger.warn( | |
| `createInternalBootPool unable to resolve boot device input='${bootDevice}'` | |
| ); | |
| continue; | |
| if (!resolved) { | |
| this.logger.warn( | |
| `createInternalBootPool unable to resolve boot device input='${bootDevice}'` | |
| ); | |
| output.push( | |
| `efibootmgr skipped unresolved boot device input='${bootDevice}'` | |
| ); | |
| hadFailures = true; | |
| continue; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In
`@api/src/unraid-api/graph/resolvers/onboarding/onboarding-internal-boot.service.ts`
around lines 345 - 349, In createInternalBootPool, when a bootDevice input fails
to resolve (where resolved is falsy and you currently call this.logger.warn with
the message including bootDevice), set the hadFailures flag to true before
continuing so the overall result reflects the failure; update the unresolved
branch (the block that logs `createInternalBootPool unable to resolve boot
device input='${bootDevice}'`) to assign hadFailures = true and then continue.
- Purpose: ensure API-created USB flash UEFI entries include an explicit loader path. - Before: the API BIOS update flow created 'Unraid Flash' with efibootmgr using only disk/partition/label and no -l loader path. - Problem: some firmware can leave the entry non-bootable in UEFI mode when loader path is omitted, even if EFI files are present on disk. - Change: append '-l \EFI\BOOT\BOOTX64.EFI' when creating the flash entry in the onboarding internal-boot service. - How: reused the existing EFI_BOOT_PATH constant and updated the unit test expectation to assert the exact efibootmgr args for flash entry creation.
- Purpose: ensure onboarding sends stable serial-based device identifiers to CreateInternalBootPool. - Before: internal boot selection used disk.id as option value and persisted that in onboardingDraft, which could propagate IDs unsuitable for efibootmgr resolution paths. - Problem: some environments surface non-kernel IDs that later fail BIOS entry updates, producing warnings and invalid /dev/<id> attempts. - Change: use disk.serialNum as the canonical option value, with fallback only when serial is unavailable. - How: added alias mapping so persisted legacy id/device values still hydrate to current serial-based options; updated summary label mapping to resolve serial/id/device keys consistently.
- Purpose: keep internal boot selection strictly serial-first without backward compatibility behavior. - Before: form initialization and summary mapping translated legacy id/device values to new serial-based options. - Problem: this added extra compatibility logic you do not want to carry. - Change: removed alias fields and persisted-value remapping from the internal boot step, and removed extra summary label aliases for serial/id. - How: selection now reads/writes the raw serial-first values directly, with no legacy id translation layer.
- Purpose: surface raw emhttp device payload and resolution decisions during BIOS boot entry updates. - Before: device map misses silently fell back to /dev/<id>, making efibootmgr failures hard to diagnose from onboarding output alone. - Problem: we could not see what getters.emhttp().devices contained at runtime or whether each selected boot device was mapped or fallback. - Change: append diagnostic lines to mutation output with raw emhttp.devices data, parsed id->device map entries, and per-device resolution source/result. - How: added safe JSON serialization helper and instrumented getDeviceMapFromEmhttpState + createInternalBootEntries resolution logging.
- Purpose: provide thorough observability for CreateInternalBootPool execution and BIOS update mapping behavior. - Before: logs were limited and did not consistently show mutation input, per-step command flow, map contents, and resolution path decisions in server logs. - Problem: diagnosing id-to-device mapping failures required inference and lacked direct evidence at each stage. - Change: added debug/warn logs for received input, each emcmd step start/success/failure, efibootmgr args/results, emhttp.devices raw+parsed map, per-device resolution source/result, BIOS update lifecycle, and final outcome. - How: instrumented runStep, runEfiBootMgr, getDeviceMapFromEmhttpState, createInternalBootEntries, createFlashBootEntry, updateBootOrder, updateBiosBootEntries, and createInternalBootPool.
- Purpose: make BIOS entry creation use the same assignable disk snapshot the UI/API already exposes instead of rebuilding device resolution later from emhttp state. - Before: createInternalBootPool created the pool with serial-based disk IDs, then tried to remap those IDs to /dev paths from emhttp.devices and fell back to /dev/<serial> when the lookup missed. - Why that was a problem: stale or incomplete emhttp state produced bogus efibootmgr device paths like /dev/TOSHIBA_..., which guaranteed BIOS update warnings even when pool creation itself succeeded. - What changed: the mutation now snapshots assignableDisks up front, treats serialNum as the canonical input identifier, uses that serial for cmdAssignDisk, and uses the matched disk.device path for efibootmgr. - How it works: unresolved serials are warned and skipped for BIOS entry creation, the broken fallback path generation was removed, and the onboarding service spec was updated to cover the new resolution flow and skip behavior.
e1a1b50 to
2ea7198
Compare
|
This plugin has been deployed to Cloudflare R2 and is available for testing. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2ea7198c84
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const resolvedBootDevices = input.updateBios | ||
| ? await this.resolveRequestedBootDevices(input.devices, output) | ||
| : new Map<string, ResolvedBootDevice>(); |
There was a problem hiding this comment.
Defer disk-resolution errors until BIOS update step
createInternalBootPool now awaits resolveRequestedBootDevices before running any emcmd pool-creation commands, so a failure in disksService.getAssignableDisks() aborts the entire operation with code 1 when updateBios is true. Since BIOS updates are handled as best-effort warnings elsewhere in this flow, this change can block onboarding entirely due to transient disk-enumeration failures that are unrelated to creating the internal boot pool.
Useful? React with 👍 / 👎.
| const bootId = disk.serialNum.trim(); | ||
| const devicePath = disk.device.trim(); | ||
| if (bootId.length === 0 || devicePath.length === 0) { | ||
| continue; |
There was a problem hiding this comment.
Keep non-serial disk fallback in boot-device resolution
The resolution map is keyed only by disk.serialNum and drops entries when that value is empty, but the onboarding UI still falls back to device when serial/id are unavailable (serial || diskId || device). For those disks, updateBios now silently skips EFI entry creation because the submitted device value can never be resolved, whereas the prior logic supported device-based fallback.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
♻️ Duplicate comments (2)
api/src/unraid-api/graph/resolvers/onboarding/onboarding-internal-boot.service.ts (2)
294-315:⚠️ Potential issue | 🟠 MajorDon't send raw
assignableDisksmappings back inoutput.
outputis part of the resolver response, and the onboarding flow already surfacesresult.outputback to the browser on failure paths. These two pushes reintroduce client-visible serial numbers and/dev/*mappings for every assignable disk. Keep the full payload inlogger.debug(...)and return only a redacted count/summary here.Suggested redaction
const snapshot = assignableDisks.map((disk) => ({ id: disk.id, serialNum: disk.serialNum, device: disk.device, })); - output.push(`assignableDisks snapshot: ${this.stringifyForOutput(snapshot)}`); + output.push(`assignableDisks snapshot count: ${snapshot.length}`); this.logger.debug( `createInternalBootPool assignableDisks snapshot=${this.stringifyForOutput(snapshot)}` ); @@ - output.push( - `assignableDisks resolved serialNum->device: ${this.stringifyForOutput(Array.from(resolved.entries()))}` - ); + const resolvedRequestedCount = bootIds.filter((bootId) => resolved.has(bootId)).length; + output.push( + `assignableDisks resolved requested devices: ${resolvedRequestedCount}/${bootIds.length}` + ); this.logger.debug( `createInternalBootPool assignableDisks resolved serialNum->device=${this.stringifyForOutput(Array.from(resolved.entries()))}` );🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api/src/unraid-api/graph/resolvers/onboarding/onboarding-internal-boot.service.ts` around lines 294 - 315, The two places that push full assignableDisks/resolved serial->device data into the response output (the output.push calls around assignableDisks and resolved) must be replaced with a redacted summary: keep the detailed payload only in logger.debug (leave the existing this.logger.debug(...) calls), and change the output.push(...) lines to append a non-sensitive summary such as the count of assignableDisks and/or a masked placeholder (e.g., "assignableDisks count: N" or "assignableDisks resolved count: N") using the same variables (output, assignableDisks, resolved, stringifyForOutput) so the public resolver response no longer contains raw serialNum or devicePath values while internals still log full details in createInternalBootPool.
318-330:⚠️ Potential issue | 🟠 MajorPropagate unresolved boot IDs into the BIOS warning state.
resolveRequestedBootDevices()records when a requested disk cannot be mapped, but that signal is dropped. If the remainingefibootmgrcalls succeed, this path still ends in the success summary even though one requested boot entry was skipped. The summary step only treatswith warningsorefibootmgr failedmarkers as BIOS trouble, so this produces a false green result.Suggested fix
+type ResolvedBootDeviceResolution = { + devices: Map<string, ResolvedBootDevice>; + hadUnresolved: boolean; +}; + private async resolveRequestedBootDevices( bootIds: string[], output: string[] - ): Promise<Map<string, ResolvedBootDevice>> { + ): Promise<ResolvedBootDeviceResolution> { this.loadEmhttpBootContext(true); const assignableDisks = await this.disksService.getAssignableDisks(); @@ - for (const bootId of bootIds) { + let hadUnresolved = false; + for (const bootId of bootIds) { if (resolved.has(bootId)) { continue; } + hadUnresolved = true; const warning = `Unable to resolve boot device for serial '${bootId}' from assignableDisks; skipping BIOS entry creation for this disk.`; output.push(warning); this.logger.warn( `createInternalBootPool could not resolve serial='${bootId}' from assignableDisks` ); } - return resolved; + return { devices: resolved, hadUnresolved }; } @@ - const resolvedBootDevices = input.updateBios + const bootResolution = input.updateBios ? await this.resolveRequestedBootDevices(input.devices, output) - : new Map<string, ResolvedBootDevice>(); + : { + devices: new Map<string, ResolvedBootDevice>(), + hadUnresolved: false, + }; @@ const biosUpdateResult = await this.updateBiosBootEntries( input.devices, - resolvedBootDevices, + bootResolution.devices, output ); + const hadBiosWarnings = + biosUpdateResult.hadFailures || bootResolution.hadUnresolved; this.logger.debug( - `createInternalBootPool BIOS boot entry updates completed hadFailures=${biosUpdateResult.hadFailures}` + `createInternalBootPool BIOS boot entry updates completed hadFailures=${hadBiosWarnings}` ); output.push( - biosUpdateResult.hadFailures + hadBiosWarnings ? 'BIOS boot entry updates completed with warnings; manual BIOS boot order changes may still be required.' : 'BIOS boot entry updates completed successfully.' );Also applies to: 512-514, 559-566
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api/src/unraid-api/graph/resolvers/onboarding/onboarding-internal-boot.service.ts` around lines 318 - 330, The loop over bootIds in createInternalBootPool drops the fact that a bootId couldn't be resolved (it only logs and pushes a warning message to output), so callers can still treat the run as success; change the code that handles unresolved boot IDs (the block that currently builds warning and calls this.logger.warn inside createInternalBootPool) to also propagate a BIOS-warning marker/state back to the caller — e.g., set a boolean like biosWarning = true or push a canonical warning sentinel into the same summary/output aggregation used by the summary step (the one that looks for "with warnings" / "efibootmgr failed"), and return or expose that marker alongside resolved (or mutate the shared output collection) so resolveRequestedBootDevices/createInternalBootPool callers see and surface the BIOS warning in the final summary.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In
`@api/src/unraid-api/graph/resolvers/onboarding/onboarding-internal-boot.service.ts`:
- Around line 294-315: The two places that push full assignableDisks/resolved
serial->device data into the response output (the output.push calls around
assignableDisks and resolved) must be replaced with a redacted summary: keep the
detailed payload only in logger.debug (leave the existing this.logger.debug(...)
calls), and change the output.push(...) lines to append a non-sensitive summary
such as the count of assignableDisks and/or a masked placeholder (e.g.,
"assignableDisks count: N" or "assignableDisks resolved count: N") using the
same variables (output, assignableDisks, resolved, stringifyForOutput) so the
public resolver response no longer contains raw serialNum or devicePath values
while internals still log full details in createInternalBootPool.
- Around line 318-330: The loop over bootIds in createInternalBootPool drops the
fact that a bootId couldn't be resolved (it only logs and pushes a warning
message to output), so callers can still treat the run as success; change the
code that handles unresolved boot IDs (the block that currently builds warning
and calls this.logger.warn inside createInternalBootPool) to also propagate a
BIOS-warning marker/state back to the caller — e.g., set a boolean like
biosWarning = true or push a canonical warning sentinel into the same
summary/output aggregation used by the summary step (the one that looks for
"with warnings" / "efibootmgr failed"), and return or expose that marker
alongside resolved (or mutate the shared output collection) so
resolveRequestedBootDevices/createInternalBootPool callers see and surface the
BIOS warning in the final summary.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 20c0cadc-c320-4c0b-8c48-a2fce2bd8b57
📒 Files selected for processing (4)
api/src/unraid-api/graph/resolvers/onboarding/onboarding-internal-boot.service.spec.tsapi/src/unraid-api/graph/resolvers/onboarding/onboarding-internal-boot.service.tsweb/src/components/Onboarding/steps/OnboardingInternalBootStep.vueweb/src/components/Onboarding/steps/OnboardingSummaryStep.vue
🚧 Files skipped from review as they are similar to previous changes (1)
- web/src/components/Onboarding/steps/OnboardingInternalBootStep.vue
🤖 I have created a release *beep* *boop* --- ## [4.30.0](v4.29.2...v4.30.0) (2026-03-18) ### Features * add internal boot step to onboarding flow ([#1881](#1881)) ([337aecc](337aecc)) * Add TPM licensing availability to registration ([#1908](#1908)) ([aa162eb](aa162eb)) * add UPS power ([#1874](#1874)) ([b531aed](b531aed)) * **api:** alert when usb boot has internal boot target ([#1898](#1898)) ([b94df47](b94df47)) * **api:** expose internal boot devices in array GraphQL ([#1894](#1894)) ([0736709](0736709)) * docker overview ([#1855](#1855)) ([9ef1cf1](9ef1cf1)) * **docker:** add update actions to container context menu ([#1867](#1867)) ([4ca3e06](4ca3e06)) * **docker:** disable containers page file modification ([#1870](#1870)) ([aaa0372](aaa0372)) * issues/1597: Temperature Monitoring - Thanks @MitchellThompkins ([a1be458](a1be458)) * New Crowdin updates ([#1809](#1809)) ([a7b3f07](a7b3f07)) * New Crowdin updates ([#1883](#1883)) ([14a8fa8](14a8fa8)) * **onboarding:** add new onboarding flows for Unraid OS ([#1746](#1746)) ([15bd747](15bd747)) * registration and trial actions use Account app ([#1928](#1928)) ([c2c0425](c2c0425)) * share internal boot state ([#1921](#1921)) ([8e4d44d](8e4d44d)) * **web:** show TPM move control for trial licenses ([#1911](#1911)) ([d00fb63](d00fb63)) ### Bug Fixes * Add dedicated TPM license move option ([#1909](#1909)) ([36c56f7](36c56f7)) * allow free USB targets in onboarding internal boot setup ([#1903](#1903)) ([298da54](298da54)) * API key key display truncation ([#1890](#1890)) ([b12f75c](b12f75c)) * **api:** harden PHP wrapper args for newer PHP versions ([#1901](#1901)) ([849f177](849f177)) * **api:** prevent flash notification startup fd exhaustion ([#1893](#1893)) ([4b231ad](4b231ad)) * clear stale onboarding modal session state ([#1904](#1904)) ([23f7836](23f7836)) * consistently clear onboarding draft ([#1916](#1916)) ([199d803](199d803)) * correct graphql-api.log timestamp formatting ([#1918](#1918)) ([243c5a8](243c5a8)) * **deps:** pin dependencies ([#1878](#1878)) ([db88eb8](db88eb8)) * **docker:** change "visit" to "webui" & use correct link ([#1863](#1863)) ([cab0880](cab0880)) * **docker:** improve start/stop UX with visual feedback ([#1865](#1865)) ([c084e25](c084e25)) * **docker:** remove aggressive caching to ensure data correctness ([#1864](#1864)) ([1c1bae8](1c1bae8)) * **docker:** sync template mappings in organizer to prevent false orphan warnings ([#1866](#1866)) ([38a6f0c](38a6f0c)) * onboarding internal-boot warning panel contrast and semantics ([#1927](#1927)) ([bb6f241](bb6f241)) * **onboarding:** add explicit EFI loader path for flash entry ([#1926](#1926)) ([429b438](429b438)) * **onboarding:** extend onboarding refresh timeout ([#1925](#1925)) ([e2a5f44](e2a5f44)) * **onboarding:** persist installed plugins in summary ([#1915](#1915)) ([07f4ebd](07f4ebd)) * **onboarding:** refine storage boot setup UX ([#1900](#1900)) ([1108d0a](1108d0a)) * polish onboarding flow ([#1902](#1902)) ([8742cac](8742cac)) * preserve registration device limits after refresh ([#1905](#1905)) ([234bfc7](234bfc7)) * prevent onboarding on API errors ([#1917](#1917)) ([540d6f9](540d6f9)) * remap TPM guid prefix to 01 ([#1924](#1924)) ([5360b5b](5360b5b)) * Return null for corrupted/invalid API key files and add Connect fixtures test ([#1886](#1886)) ([013e6c5](013e6c5)) * share internal boot state across onboarding ([#1920](#1920)) ([f9b293f](f9b293f)) * too many file descriptors with thousands of notifications ([#1887](#1887)) ([7956987](7956987)) * Treat onboarding patch updates as completed ([#1884](#1884)) ([d03b25e](d03b25e)) * unify onboarding internal boot state refresh ([#1923](#1923)) ([d3032c1](d3032c1)) * **web:** refresh internal boot onboarding state ([#1913](#1913)) ([1ca2129](1ca2129)) * **web:** stop showing callback errors after successful key installs ([#1892](#1892)) ([45f1402](45f1402)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please). Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Summary
Why
Some motherboards fail to boot the USB entry in UEFI mode when the NVRAM boot entry is created without an explicit loader path, even when
EFI/BOOT/BOOTX64.EFIexists.Change Details
-l \EFI\BOOT\BOOTX64.EFITesting
pnpm --filter ./api test src/unraid-api/graph/resolvers/onboarding/onboarding-internal-boot.service.spec.tsvitest: command not found)Summary by CodeRabbit
Bug Fixes
Improvements
Tests