feat: surface missing coder_secret requirements with a dialog on workspace update#25375
Draft
zedkipp wants to merge 1 commit into
Draft
feat: surface missing coder_secret requirements with a dialog on workspace update#25375zedkipp wants to merge 1 commit into
zedkipp wants to merge 1 commit into
Conversation
Docs preview📖 View docs preview for |
cc68933 to
efebab2
Compare
zedkipp
commented
May 15, 2026
| </DialogDescription> | ||
| <DialogDescription> | ||
| Would you like to go to the user secrets page to review and update | ||
| secrets before continuing? |
Contributor
Author
16108b2 to
cb806c6
Compare
…space update When an update build fails because the active template version declares coder_secret requirements the workspace owner has not satisfied, surface a dedicated dialog with a count and a placeholder action to navigate to the user-secrets page. Mirrors the existing dynamic-parameter dialog behavior so the two failure modes route through structurally identical UX. Introduce a workspace-build-scoped error envelope rather than widening codersdk.Response. codersdk.WorkspaceBuildErrorResponse is structurally a superset of codersdk.Response, with a kinded validations slice (WorkspaceBuildValidationError) whose Kind discriminator lets the frontend route entries between parameter validation failures and missing coder_secret requirements within a single response. The two new constants are WorkspaceBuildValidationErrorKindMissingSecretEnv and WorkspaceBuildValidationErrorKindMissingSecretFile. Other endpoints' codersdk.Response / codersdk.ValidationError schemas are unchanged. Internally, missing secrets flow as keyed hcl.Diagnostics whose Extra carries a previewtypes.DiagnosticExtra with the matching code. DiagnosticError.BuildResponse() reads the code via ExtractDiagnosticExtra and translates it to a WorkspaceBuildValidationErrorKind. DiagnosticError.Response() (used by non-build consumers like tag validation and chatd introspection) still emits the generic codersdk.Response shape with no kind information. WriteWorkspaceBuildError checks for WorkspaceBuildResponder first, then promotes any generic Responder result into the build envelope, so the build endpoint consistently emits WorkspaceBuildErrorResponse. The Go to user secrets button is rendered for layout parity but disabled; PLAT-102 builds the user-secrets page and once it lands we will wire the destination here.
cb806c6 to
1b8d45c
Compare
zedkipp
commented
May 15, 2026
| // appropriate dialog. Parameter validations take priority: they | ||
| // surface during stop+start, while secret requirements only fire | ||
| // on start, so a workspace that has both will typically discover | ||
| // parameters first. |
Contributor
Author
There was a problem hiding this comment.
This comment isn't totally accurate. I think it should read When the response carries both parameter and missing-secret entries, surface the parameter dialog first. Missing secrets re-surface on the next build attempt.
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.

When
coder_secretrequirements are introduced in a new template version, an in-flight update build fails onstartwith a400carrying the missing secret descriptors. Without dedicated handling, the user lands on the generic build-failed dialog with no actionable guidance.This mirrors the existing dynamic-parameter recovery flow: classify the failure on the client, surface a dedicated dialog with the count of missing secrets, and present a placeholder action button to navigate to the user-secrets page.
Introduces a workspace-build-scoped error envelope,
codersdk.WorkspaceBuildErrorResponse, rather than widening the sharedcodersdk.Response. It is structurally a superset ofResponsewith a kinded validations slice whoseKinddiscriminator (missing_secret_envormissing_secret_file) lets the frontend route entries between parameter validation failures and missingcoder_secretrequirements within a single response.GIF of this in action (note that the two required secrets are for the env and file added in a single

coder secret createcommand):Implementation notes
codersdk (new types, build-scoped)
codersdk.WorkspaceBuildErrorResponse: superset ofcodersdk.Response. Returned by workspace build endpoints (postWorkspaceBuilds).codersdk.WorkspaceBuildValidationError: mirrorsValidationErrorplus an optionalKinddiscriminator.codersdk.WorkspaceBuildValidationErrorKindand the twoWorkspaceBuildValidationErrorKindMissingSecret{Env,File}constants.codersdk.Responseandcodersdk.ValidationErrorare unchanged frommain.Backend wiring
coderd/dynamicparameters/error.go:DiagnosticErrorkeeps its existingResponse()method (returns genericcodersdk.Response, used by tag validation, preset validation, and chatd introspection). AddsBuildResponse()returningcodersdk.WorkspaceBuildErrorResponsewith per-entryKindpopulated from each keyed diagnostic'sExtra.Code.coderd/dynamicparameters/resolver.go: iteratesSecretRequirementsand appends one keyedhcl.Diagnosticper unsatisfied requirement. The diagnostic key is the env or file name;Extracarries apreviewtypes.DiagnosticExtrawhoseCoderecords whether the requirement is env- or file-shaped.coderd/wsbuilder/wsbuilder.go:BuildErrorgainsBuildResponse()mirroring its existingResponse(). Delegates througherrors.Asone.Wrappedto avoid recursion.coderd/httpapi/httperror: newWorkspaceBuildResponderinterface andIsWorkspaceBuildResponderhelper.WriteWorkspaceBuildErrorchecks for it first, then promotes any genericResponderresult into the build envelope so the build endpoint consistently emitsWorkspaceBuildErrorResponse.coderd/workspacebuilds.go: the non-validation 409 (deleted-workspace guard) is rewritten to emitWorkspaceBuildErrorResponsedirectly. Swagger annotations onpostWorkspaceBuildsadd explicit@Failure 400and@Failure 409for the new envelope.Frontend
site/src/api/errors.ts:FieldErrorkeeps the optionalkindfield; doc comment updated to point atWorkspaceBuildValidationErrorKind.site/src/api/api.ts: newMissingSecretsError.updateWorkspace's catch block filters validations into parameter entries first (existingParameterValidationError), and falls back to entries whosekindis in the generatedWorkspaceBuildValidationErrorKindsset (MissingSecretsError).site/src/modules/workspaces/WorkspaceMoreActions/MissingSecretsDialog.tsx: dialog mirroringUpdateBuildParametersDialogExperimental. Body is count-only; no env-name list.site/src/modules/workspaces/WorkspaceUpdateDialogs.tsx: adds amissingSecretsdialog wired offerror instanceof MissingSecretsError.Scope
Only the
updateWorkspaceflow is updated.changeWorkspaceVersion,startWorkspace, and the experimental workspace-parameters page surface throughWorkspaceErrorDialogas before; widening scope is out of band with the original PLAT-81 brief.Counting caveat
Secret requirements are keyed by their env or file name, so the unlikely case of two
SecretRequirementStatusentries colliding on the same name would collapse into a singleWorkspaceBuildValidationError. Preview already deduplicates upstream, so this is a documented edge rather than an observed regression.This PR was generated by Coder Agents on behalf of @zedkipp.