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 }}
Repository navigation
bug(plans): create-plan reported no success/error feedback (QA standard user) — verify vs deploy lag #949
QA (standard-user session) reported that creating a Purchase Plan produces no result and no error/success feedback. Covers two QA sheet rows with the same root cause.
Steps / Expected / Actual
Row 547 — Plan from Opportunities
Action: On Opportunities, select a commitment, click "Plan from 1 selected".
Expected: Plan is created.
Actual: Nothing happens; the Create Purchase Plan modal stays open; no success message.
Row 548 — New Plan from Plans page
Action: On Plans page, click "New Plan", configure details, submit.
Expected: Plan is created.
Actual: Same; nothing happens; modal stays open; no success/error feedback.
Investigation against current base (feat/multicloud-web-frontend @ #883)
Read the full create-plan path FE + BE on the current base:
Frontend savePlan (frontend/src/plans.ts:1099): wraps the create call in try/catch. On success it closes the modal, reloads plans, and shows a Plan created successfully toast. On any error it keeps the modal open and shows a Failed to save plan: <message> toast. showToast is imported and wired.
apiRequest (frontend/src/api/client.ts:253): on a non-2xx response it parses the JSON body, reads the error field, and throws an Error carrying that message (and structured details).
Backend createPlan (internal/api/handler_plans.go:65) + handleRequestError (internal/api/handler.go:372): every failure path returns a JSON body {"error": "..."} — NewClientError for 400/401/403/404 and {"error":"Internal server error"} for the generic 500 case.
Permission gate is NOT the cause.createPlan requires create:plans. DefaultUserPermissions() (internal/auth/types.go:466) grants standard users create:plans and update:plans. The Purchaser-group work (#923/#924) only carves execute / approve-any / retry-any on purchases out of the admin wildcard; it does not touch create:plans. So a standard user is authorized to create plans on the current base.
Conclusion: On the current base the create-plan flow is fully wired for feedback. Success shows a toast and closes the modal; any error (including 403 / 400 / 404 / 500) keeps the modal open and shows a toast with the backend message. There is no silent-failure code path. The savePlan error toast has been present since 2026-03-23 (0ca70ef48).
Reproduces for: neither admin nor standard user on the current base — both get explicit toast feedback.
Most likely cause of the QA observation
Deploy lag. #907/#912 (group-only authz) and #924 (Purchaser group) only reached prod in today's deploy; the QA session very likely ran against a frontend bundle and/or backend that predates the wired-up feedback path or hit a transient backend error. The deployed frontend bundle is built and shipped from this branch, so a stale CDN/bundle can present old behavior even after the backend updates.
A related, already-tracked structural defect is #944 (createPlan returns an opaque 500 with no structured log), which has open PR #946 (fix/create-plan-500-observability). That improves backend root-causing but the user-facing feedback is already correct on the current base.
Recommended action
Re-test on the current deploy (post today's deploy) as both admin and standard user. Capture the browser Network tab for POST /api/plans (status + response body) and the toast, if any.
If the re-test still shows no toast, this becomes a live frontend bug — attach the captured request/response and reopen scope; otherwise close as deploy-lag.
Summary
QA (standard-user session) reported that creating a Purchase Plan produces no result and no error/success feedback. Covers two QA sheet rows with the same root cause.
Steps / Expected / Actual
Row 547 — Plan from Opportunities
Row 548 — New Plan from Plans page
Investigation against current base (
feat/multicloud-web-frontend@ #883)Read the full create-plan path FE + BE on the current base:
savePlan(frontend/src/plans.ts:1099): wraps the create call intry/catch. On success it closes the modal, reloads plans, and shows aPlan created successfullytoast. On any error it keeps the modal open and shows aFailed to save plan: <message>toast.showToastis imported and wired.apiRequest(frontend/src/api/client.ts:253): on a non-2xx response it parses the JSON body, reads theerrorfield, and throws anErrorcarrying that message (and structureddetails).createPlan(internal/api/handler_plans.go:65) +handleRequestError(internal/api/handler.go:372): every failure path returns a JSON body{"error": "..."}—NewClientErrorfor 400/401/403/404 and{"error":"Internal server error"}for the generic 500 case.Permission gate is NOT the cause.
createPlanrequirescreate:plans.DefaultUserPermissions()(internal/auth/types.go:466) grants standard userscreate:plansandupdate:plans. The Purchaser-group work (#923/#924) only carvesexecute/approve-any/retry-anyon purchases out of the admin wildcard; it does not touchcreate:plans. So a standard user is authorized to create plans on the current base.Conclusion: On the current base the create-plan flow is fully wired for feedback. Success shows a toast and closes the modal; any error (including 403 / 400 / 404 / 500) keeps the modal open and shows a toast with the backend message. There is no silent-failure code path. The
savePlanerror toast has been present since 2026-03-23 (0ca70ef48).Reproduces for: neither admin nor standard user on the current base — both get explicit toast feedback.
Most likely cause of the QA observation
Deploy lag. #907/#912 (group-only authz) and #924 (Purchaser group) only reached prod in today's deploy; the QA session very likely ran against a frontend bundle and/or backend that predates the wired-up feedback path or hit a transient backend error. The deployed frontend bundle is built and shipped from this branch, so a stale CDN/bundle can present old behavior even after the backend updates.
A related, already-tracked structural defect is #944 (createPlan returns an opaque 500 with no structured log), which has open PR #946 (
fix/create-plan-500-observability). That improves backend root-causing but the user-facing feedback is already correct on the current base.Recommended action
POST /api/plans(status + response body) and the toast, if any.No deploy-independent code fix is warranted from the current-base reading: the feedback path is correct and standard users are authorized.