fix(i18n): define the two missing oauth error strings, and gate the rest in CI - #223
Merged
Conversation
…est in CI `errorMessage()` falls back to returning the key when the dictionary has no entry, so `oauth.grant_not_found` and `oauth.revoke_forbidden` have been shipping as their own key names in the revoke endpoint's HTTP error body ever since the connected-apps panel landed. That panel swallows the server message behind a generic toast, so this never showed in its UI — it surfaces to direct API callers and in error reporting. Nothing caught it: a missing key fails no lint rule, no type, and no test, because the fallback makes it a silent degradation rather than an error. `check:strings` has existed the whole time and was simply never wired up. It now runs in CI next to lint, so the next one fails the build instead of shipping.
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.
Follow-up to the note at the end of #219.
The bug
errorMessage()returns the key itself when the dictionary has no entry:Two keys thrown by
DELETE /api/workspaces/:workspaceId/connected-apps/:grantIdwere never defined, so the endpoint has been answering with the literal stringsoauth.grant_not_foundandoauth.revoke_forbiddenas its error message.Scope correction from my note on #219: I said these show to users as raw keys. In the connected-apps panel they do not —
handleRevokecatches and shows its ownconnected_apps.revoke_errortoast, discarding the server message. The keys surface in the HTTP error body for direct API callers and in error reporting, not in that UI. Worth fixing, smaller blast radius than I implied.The fix
Two dictionary entries, matching the tone of the neighbouring
oauth.*strings:oauth.grant_not_found— "Connected app not found. It may already have been revoked."oauth.revoke_forbidden— "You can only revoke apps you connected yourself. Ask a workspace owner or admin to revoke this one."Why it went unnoticed, and why that part matters more
A missing key fails nothing. Not lint, not
typecheck, not any test — the fallback turns a missing string into a silent degradation instead of an error. There is no signal until someone reads an error body and sees a dotted identifier.pnpm check:strings(scripts/check-dictionary-keys.mjs) has existed the whole time and catches exactly this. It was simply never wired into CI. It now runs next to Lint in thecijob, so the next missing key fails the build.The script already separates dynamic call sites (
t(\content.status_${'$'}{value}`)` and friends) into a manual-review list that does not fail, so the 16 existing dynamic usages stay non-blocking. It exits non-zero only on literal keys with no entry — currently none.Verification
pnpm check:strings→✓ All literal dictionary keys are defined.