Skip to content

console: the record create/edit dialog shows only "You don't have permission to save this record." on a controlled_by_parent master-edit refusal, dropping the API's reason ("requires edit access to its master record"); #7366 regression on this path #33524

Open

Description

@objectstack-fleet

repo:hotcrm#1 · huangyiirene · session_01J8VVAnPkgK6CWrJa6t7Fk5

What happens (@objectstack 18.4.0, measured by HotCRM's Order to Cash browser pass on 2026-11-14)

A user who reads a contract but does not edit it opens the create dialog of a controlled_by_parent detail (HotCRM crm_billing_milestone, crm_invoice) and saves. The API answers 403 with a reason saying the write requires edit access to its master record. The console shows only the generic toast: "You don't have permission to save this record." The user cannot tell that the missing access is on the contract, not on the record they are creating.

#7366 (closed) fixed "Console discards the server error message on 403". This path either does not take that fix or has regressed.

Ask

On a 403 whose envelope carries a userMessage (or a master-chain reason), the create and edit dialogs show it, as they do for other refusals.

Acceptance

  1. A master-edit refusal on create shows the server's reason, naming the master object, in the dialog or toast, in en and zh-CN.
  2. The same applies on edit.
  3. A refusal with no userMessage keeps the generic line.

Activity

  1. objectstack-fleet commented on Nov 14, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · hotlong · session_01Q4EjjMnyLqJdzuktEmRPXH

    Path: none

    Triage: first touch → domain:ui · p2 · pm:queue · 2026-11-14T23:44Z

    ⛔ Not a claim.

    The refusal is loud, but the console drops the reason that says which record needs edit access. On its own that is p3 copy. HotCRM's Order to Cash users hit it on 18.4.0, so it is raised once to p2. It looks like the #7366 fix does not cover the create/edit dialog path: check which error shape that path reads.

  2. added
    bugSomething isn't working
    domain:uiDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    on Nov 14, 2026
  3. objectstack-fleet commented on Nov 15, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#2 · os-project-manager · session_01FEkQ5oF8GgTHN2jBZoDwz8

    Claim: PM loop round 1 · 2026-11-15T00:13Z
    Session: session_01FEkQ5m1xDT63aCaQJNjwXD (card thread, dev) · seat session_01FEkQ5oF8GgTHN2jBZoDwz8
    Account: os-project-manager
    Branch: claude/project-thread-bhbxol
    Worktree: objectstack-issue-33524
    Domain: domain:ui
    Seat: domain:ui#2
    File surface: ui/apps/console/src/components/FormPage.tsx (the permission-refusal text), the plugin-form modal/drawer submit refusal path if that is the create dialog, ui/packages/app-shell/src/providers/saveAdvisoryToast.ts, the error-toast reader in ui/packages/app-shell/src/utils/ (flowResponse.ts), their tests, i18n packs only if a key is truly new, root .changeset/. The dev declares the final files per half at first hand-back. ⛔ No packages/spec, server or cloud edit.
    Container & model: M, mode:thread, model: default tier, effort: default
    Clause-②: no
    Metadata-protocol: none
    Responsibility: the console's create/edit dialog replaces a 403's producer userMessage (plugin-security's master-edit refusal) with the generic permission line | the producer already sends the localized reason (#33290) | every user saving a controlled_by_parent detail without edit access on its master (HotCRM Order to Cash)
    Thread-read: 6886080721
    Premise: read at filing on 18.4.0 by HotCRM's browser pass; not re-measured by the seat; the dev measures on origin/main first
    Serial constraints cleared: no other pm:dispatched domain:ui card claims a file in this surface (live label read; ui seat 1's live files #33317 #33063 #33061 #33103 #33377 are disjoint); no other ui seat holds a Claim: on these files

    Scope: shared card thread with #32657 (one dev, one PR Fixes #33524 + Fixes #32657 if both halves land, else one PR per card). p2. Order: /mnt/project-files/pm-orders/ui/order-33524.md. Summons: the maintainer's 「同意 给队列最深的 ui 和 spec 各再开一个座位」 (this project, 2026-11-14T22:46Z).

  4. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 15, 2026
  5. objectstack-fleet commented on Nov 15, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#2 · os-project-manager · session_01FEkQ5oF8GgTHN2jBZoDwz8

    Claim amendment · Premise: corrected · 2026-11-15T00:16Z · to claim 6886417201. Dev's measurement on e3f0cfd4 (/mnt/project-files/pm-orders/ui/33524-measurement.md):

    • The create dialog HotCRM opens is the console's modal form, and its renderer already reads the producer's userMessage first (as do the record form page and the edit conflict path). The generic "You don't have permission to save this record." shows only when the refusal carries no userMessage.
    • The master-edit refusal carries none: packages/plugins/plugin-security/src/security-plugin-cbp-write-gate.ts (~L463, the master-edit denial) throws a bare permission error with English developer prose and no user message. fix(plugin-security): permission refusals speak the caller's language, falling back to the workspace default (#32656, 2/2) #33290 localized the other permission refusals, not this one.
    • So acceptance 1 and 2 are a server fix (plugin-security composes a localized userMessage naming the master record), outside the ui lane.

    The ui half shrinks to rendered pins proving the dialog shows a userMessage on create and edit (en and zh-CN) and keeps the generic line without one. That ships in the shared PR as Refs #33524, with no product change. After it merges, the seat releases this card to triage with pm:retriage to re-lane it to domain:server.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workingdomain:uiDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions