Repository navigation
fix(settings): surface API error envelopes in the storage tab instead of crashing (#14846) - #14951
Merged
diegosouzapw merged 2 commits intoSep 28, 2026
Conversation
… of crashing
/api/db-backups* are always protected, so an unauthenticated dashboard
session receives the authz pipeline envelope
{ error: { code, message, correlation_id } }. SystemStorageTab used
`data.error || t(...)` as the status message, rendering that object as a
React child (settings error boundary: "Failed to load settings"), and
wrapped it in `new Error(...)` in the download helper, which produced
"Export failed: [object Object]".
Route every error-status message and the download helper through the
existing extractApiErrorMessage() helper.
Closes diegosouzapw#14846
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
In Settings > Storage, "Backup now" and "Import Database" crash the whole settings page into its error boundary ("Failed to load settings"). "Export Database" shows
Export failed: [object Object].SystemStorageTabuseddata.error || t(...)as the status message. When the API answers with the structured envelope{ error: { code, message, correlation_id } }, that object is rendered as a React child ("Objects are not valid as a React child"), which triggerssettings/error.tsx. The download helper didnew Error(data.error || fallback), which turns the object into[object Object]./api/db-backups*has been inALWAYS_PROTECTED_API_PATHSsince before v3.8.50 (the reporter's version). A dashboard session without auth therefore gets exactly this envelope from the authz pipeline (rejectionResponseinsrc/server/authz/pipeline.ts). The route handlers also return object-shapederrorvalues for validation failures (restore, retention, cleanup).Every error-status message in the tab, and
fetchAndDownload, now goes through the existingextractApiErrorMessage()(src/shared/http/apiErrorMessage.ts), the helper already used for #5340 and #5991. Plain string errors from the route handlers are shown as before.Related Issues
Closes #14846
Validation
npx vitest run tests/unit/ui/system-storage-backup-auth-envelope-14846.test.tsx: 2/2 pass. With only the component reverted to the base version, both fail withObjects are not valid as a React child (found: object with keys {code, message, correlation_id})andexportFailedWithError: [object Object].node --import tsx/esm --test tests/unit/ui/system-storage-error-envelope-14846.test.ts: 5/5 pass, 3 fail on the base version.npx vitest run tests/unit/ui/system-storage-manual-vacuum.test.tsx tests/unit/ui/system-storage-tab-guest-401-12709.test.tsx, andnode --import tsx/esm --test tests/unit/dashboard-localization-contract.test.ts tests/unit/quota-card-grid-mobile-7072.test.ts tests/unit/settings-ui-layout-static.test.ts tests/unit/api-error-message-5340.test.ts(27/27).npx eslintandnpx prettier --checkare clean on the touched files.Tests Added
tests/unit/ui/system-storage-backup-auth-envelope-14846.test.tsx: renders the tab with a 401AUTH_001envelope from/api/db-backupsand clicks "Backup now" and "Export Database". It checks that the tab stays mounted, that the envelope message is shown, and that[object Object]never appears.tests/unit/ui/system-storage-error-envelope-14846.test.ts: a source guard againstmessage: data.error ||andnew Error(data.error)in the tab, plus extractor checks on the pipeline envelope, string errors and empty bodies.Coverage Notes
The
.sqliteimport confirm flow (file input plus modal) is covered by the source guard, not by a render test. It uses the same code path as "Backup now".Reviewer Notes
[object Object].catch (err)changed tocatch {}in the legacy JSON import handler. eslint already flagged that line before this change..sqliteimport handler and adds a render-time guard. This PR fixes it at the source for every handler, including the export[object Object]message.