You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Settings save: render the dedicated SETTINGS_CRYPTO_UNAVAILABLE refusal instead of the generic error path #4570
As of that PR, the framework's fail-closed settings refusal — a declared-encrypted value (encrypted: true / manifest type: 'password') refused because the deployment has nothing able to encrypt it — answers PUT /api/settings/:namespace with a dedicated wire envelope instead of the generic one:
error.details: { namespace, key } — the located refusal (never the value)
error.message: unchanged; carries the operator prescription (wire SettingsServicePluginOptions.cryptoProvider or a real crypto adapter)
SettingsView.tsx already branches per code (SETTINGS_LOCKED is special-cased around line 152; SETTINGS_VALIDATION feeds the field-error extractor). SETTINGS_CRYPTO_UNAVAILABLE currently falls to the generic error path, which does surface the carried message — so nothing is broken; this is the client-side half the new code exists to enable: an admin saving a secret on a deployment that cannot encrypt should see "this deployment cannot encrypt secrets — reconfigure it" as a first-class state (pointing at the refused key via error.details.key), not a generic save failure.
Severity: low, enhancement-class. The framework half is done; nothing here blocks it.
CLAIM — session_017Qqyix2QcnpUC9XeYVDzx3, branch claude/issue-4570-crypto-unavailable-refusal. Dispatching a dev agent now.
PM ruling (delegated decision authority; maintainer veto window open — record objections here):
Mirror the SETTINGS_LOCKED precedent (SettingsView.tsx ~:152 — measure its exact shape first: how it detects the code, what state it renders, how it recovers). Add the SETTINGS_CRYPTO_UNAVAILABLE branch as a first-class refusal state: name the refused key from error.details.key (and namespace), carry the message's operator prescription verbatim (the server owns that copy — do not restate it client-side), and distinguish it visually the way LOCKED does from a generic failure.
The wire envelope is the fixture: red-first with the fix(plugin-detail): DetailSection shares ONE definition of emptiness, and it trims #8396 shape (status 500, code SETTINGS_CRYPTO_UNAVAILABLE, details {namespace, key}) — today it renders the generic path (pin that as the pre-fix observation), post-fix the dedicated state. Pins: SETTINGS_LOCKED and SETTINGS_VALIDATION branches byte-untouched and green; an UNKNOWN code still takes the generic path (the fallback must not narrow); the value never appears anywhere (the envelope's own never-the-value rule).
i18n through the surface's measured channel (defaults maps if that is what SettingsView uses; all-pack parity if locale packs are touched; the prescription itself stays the server's string).
Changeset: '@object-ui/app-shell' patch expected (measure via .d.ts both ways). Never major.
Mutual exclusion: SettingsView's surface is untouched by all in-flight cards (#4548 react+dashboard/report, #4566 core+DatasetWidget, #4563 apps/console entry, #4535 types+ObjectGrid exportOptions, #4567 landed). Disjoint throughout.
Activity
yinlianghui commentedon Aug 13, 2026
CLAIM — session_017Qqyix2QcnpUC9XeYVDzx3, branch
claude/issue-4570-crypto-unavailable-refusal. Dispatching a dev agent now.PM ruling (delegated decision authority; maintainer veto window open — record objections here):
error.details.key(and namespace), carry the message's operator prescription verbatim (the server owns that copy — do not restate it client-side), and distinguish it visually the way LOCKED does from a generic failure.Mutual exclusion: SettingsView's surface is untouched by all in-flight cards (#4548 react+dashboard/report, #4566 core+DatasetWidget, #4563 apps/console entry, #4535 types+ObjectGrid exportOptions, #4567 landed). Disjoint throughout.
Generated by Claude Code
Generated by Claude Code
feat(console): the settings save renders the crypto-unavailable refus…