Problem
The backend now persists TTL failure reasons in a new ttl_setting.error_message column and exposes it through GET /api/v2/settings/ttl (see PR #11994). The frontend types and the General Settings UI never read this field, so users still see only the generic "TTL is failed" status without any clue why.
Motivation
Self-hosted operators who set up S3 cold storage hit a long-standing failure mode where a typo in the bucket name, a missing ClickHouse cold storage volume, or an IAM permission issue leaves the TTL row stuck in failed. The backend already logged the underlying error, but the frontend never had a way to surface it. PR #11994 fixed the backend; this issue tracks the missing frontend wiring.
Current behavior
- User opens General Settings → Logs.
- They click "Move to S3", set a value, save.
- The save call fails server-side (e.g.
setColdStorage returns an error), the backend logs the error and writes status: failed plus error_message: "S3 disk not configured".
- The frontend polls
GET /api/v2/settings/ttl. The response shape (as typed in frontend/src/types/api/settings/getRetention.ts) only includes status, so the GeneralSettings component renders the failed status with no context.
- The user is stuck and has to grep the query-service log to find the cause.
Expected behavior
When the TTL row is in failed status, the General Settings UI should display the persisted error_message so users see the actual reason (missing bucket, IAM denial, malformed query, etc.) without leaving the UI.
Proposed solution
Two small frontend changes:
- Extend
PayloadPropsLogs in frontend/src/types/api/settings/getRetention.ts with an optional error_message?: string field so the client accepts the new backend response.
- In
frontend/src/container/GeneralSettings/GeneralSettings.tsx, when rendering the logs section, surface error_message next to the failed status. A small <Typography.Text type="danger"> under the retention card, or a tooltip on the status badge, both work; the implementation should match the existing UX patterns for warning text.
No backend, API, or schema changes — those landed in #11994.
Scope
- One type file (
getRetention.ts).
- One component file (
GeneralSettings.tsx) for the display logic.
- Optional: a small test that the GeneralSettings component renders
error_message when present.
Acceptance criteria
Backward compatibility
Adding an optional field to a TypeScript interface and rendering it only when present is fully backward compatible. Older backends that don't return error_message continue to work; newer backends that do will be displayed correctly.
Alternatives considered
- Toast on poll failure: brittle, easy to miss, no persistent place to read the cause.
- Tooltip on the status badge: viable, simpler than a banner; either is acceptable.
- Modal with full log trace: overkill; the persisted message is enough for the common case.
- Do nothing: keeps the UX gap; users keep opening log files.
References
- Backend change: PR #11994 —
fix(retention): persist TTL error message on failure
- Backend type:
pkg/types/retentiontypes/ttl.go (GetCustomRetentionTTLResponse.ErrorMessage)
- Frontend type to extend:
frontend/src/types/api/settings/getRetention.ts
- Frontend render site:
frontend/src/container/GeneralSettings/GeneralSettings.tsx
Problem
The backend now persists TTL failure reasons in a new
ttl_setting.error_messagecolumn and exposes it throughGET /api/v2/settings/ttl(see PR #11994). The frontend types and the General Settings UI never read this field, so users still see only the generic "TTL is failed" status without any clue why.Motivation
Self-hosted operators who set up S3 cold storage hit a long-standing failure mode where a typo in the bucket name, a missing ClickHouse
coldstorage volume, or an IAM permission issue leaves the TTL row stuck infailed. The backend already logged the underlying error, but the frontend never had a way to surface it. PR #11994 fixed the backend; this issue tracks the missing frontend wiring.Current behavior
setColdStoragereturns an error), the backend logs the error and writesstatus: failedpluserror_message: "S3 disk not configured".GET /api/v2/settings/ttl. The response shape (as typed infrontend/src/types/api/settings/getRetention.ts) only includesstatus, so the GeneralSettings component renders the failed status with no context.Expected behavior
When the TTL row is in
failedstatus, the General Settings UI should display the persistederror_messageso users see the actual reason (missing bucket, IAM denial, malformed query, etc.) without leaving the UI.Proposed solution
Two small frontend changes:
PayloadPropsLogsinfrontend/src/types/api/settings/getRetention.tswith an optionalerror_message?: stringfield so the client accepts the new backend response.frontend/src/container/GeneralSettings/GeneralSettings.tsx, when rendering the logs section, surfaceerror_messagenext to the failed status. A small<Typography.Text type="danger">under the retention card, or a tooltip on the status badge, both work; the implementation should match the existing UX patterns for warning text.No backend, API, or schema changes — those landed in #11994.
Scope
getRetention.ts).GeneralSettings.tsx) for the display logic.error_messagewhen present.Acceptance criteria
PayloadPropsLogsaccepts an optionalerror_messagefield.status === 'failed'anderror_messageis non-empty, the General Settings Logs card displays the error string to the user.status === 'failed'anderror_messageis absent (older backend), the UI behaves as it does today (no regression).Backward compatibility
Adding an optional field to a TypeScript interface and rendering it only when present is fully backward compatible. Older backends that don't return
error_messagecontinue to work; newer backends that do will be displayed correctly.Alternatives considered
References
fix(retention): persist TTL error message on failurepkg/types/retentiontypes/ttl.go(GetCustomRetentionTTLResponse.ErrorMessage)frontend/src/types/api/settings/getRetention.tsfrontend/src/container/GeneralSettings/GeneralSettings.tsx