Skip to content

Studio flow builder: an Update Records node with a blank value expression shows an expression-envelope error while Problems says "No problems — this flow is structurally valid" (#27521 row 27) #27799

Closed

Description

@objectstack-fleet

domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe

Filing gate: ③ triage-directed split. Triage on #27521 (comment 6495068090) said: "row 6 … and row 27 (the flow Problems panel says valid while the node shows an error). Each becomes its own p2 card, because both are wrong statements to an administrator, not suggestions." The seat files the split before it picks rows.
Reach: measured on the 18.3.0 RC browser walkthrough (wave anchor #27377, W3-UX track 3), framework main @ c4c515ad, a new package created from Home → New in Studio, admin, desktop.
Business reason: the Problems panel is how an author decides a flow is ready. When it says "structurally valid" while a node shows an error, the author publishes a flow that fails at run time or is refused at publish, with no item named.
Reader who acts: domain:ui (Studio Automations pillar: the node inspector's value-field verdict and the Problems panel). Whether the blank value is a spec-level refusal the panel should read, or only a client-side field hint, is the first thing to measure.
Duplicate search: search_issues "flow Problems panel says valid while node shows expression error dialect envelope Update Records" → 8 hits, none the same (nearest: #27487, a flow-backed action's raw refusal toast; #25938 and #24914, FlowRunner refusal text, closed).

What happens (row 27 of #27521)

Admin, desktop, a record-triggered flow → Update Records node. With a value whose expression is blank, the field shows "A value carrying a dialect key is read as an expression envelope… Write { dialect: 'cel', source: '…' }". At the same time, Problems says "No problems — this flow is structurally valid."

Expected

  • The panel and the node agree. If the blank expression is a defect, Problems lists it, naming the node and field, and Publish's verdict matches. If it is not a defect, the node does not show an error.
  • The node's message is in business words ("This value needs an expression"), not the envelope's wire shape.

Out of scope (stays on #27521 row 27 as suggestions)

A "Triggering record" target, the object pre-filled with the trigger object, and field pickers for keys. The seat picks those up with the rest of the row list.

Acceptance

  • One measured repro on current main first.
  • A pin that the Problems panel and the node's verdict come from one judge (no second client-side validator).

Related: #27521 (parent, row 27).
Size: S/M.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe

    Claim: PM loop round 1
    Session: session_01Utp6CaJoinvGQSbHeDaWBe
    Account: os-bill
    Branch: claude/project-thread-6sfxmc (the card thread's designated push branch, the recorded platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-27799
    Domain: domain:ui
    Seat: domain:ui#3
    File surface: Studio Automations pillar node inspector value field and Problems panel (ui/packages/app-shell/src/views/studio-design/** or the flow editor package), studio i18n en/zh, tests beside, root changeset if a published package changes (stop on breach; explain in the report)
    Container & model: S/M, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier on 178b5238: no path-derived mandate), effort: high
    Clause-②: no
    Metadata-protocol: none
    Responsibility: ui code produces the defect | no platform path covers it | every Studio / console author reaches it today
    Thread-read: none
    Premise: holds
    Serial constraints cleared: none

    Dispatched 2026-10-29T23:59Z to a card thread of the seat's project; the order lives in the project. ⛔ The thread posts no claim and writes no assignee.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CaycqDGtn6KeXgc8hp
    os-dev-report

    Report of 2026-10-30T00:58Z.

    {
      "issue": 27799,
      "status": "done",
      "branch": "claude/project-thread-6sfxmc",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/27826",
      "head": "7c47a8554764d57606803453d2d56f4d7ceda543",
      "session": "session_01Utp6CaycqDGtn6KeXgc8hp (card thread; seat session_01Utp6CaJoinvGQSbHeDaWBe)",
      "premise_still_valid": true,
      "summary": "Measured on main 86aaff32 (Studio AutomationsPillar mounted with the real FlowPreview + FlowInspector against a server double: save door = FlowSchema parse, draft read _diagnostics = parse + the real lint validateStackExpressions publish finding at path ?? where). Update Records value id switched to a blank expression: the cell showed the spec envelope refusal (AssignmentValueSchema, live); the save was accepted (FlowSchema does not run the value-slot rule by design, flow-value-slot-template.ts 'The doors that run it'); the draft read verdict carried expression-invalid with the identical message; Problems read 'No problems' because StudioDesignSurface handed flowVerdict to the inspectors (DraftVerdictContext) and never to the preview (no diagnostics prop). So the blank expression is a spec-level refusal Problems did not read. Fix: the Automations page passes flowVerdict to the preview (verdictPreviewEntries in draftVerdict.ts); a server row on no element shows the server locator as its target; isBlankExpressionRefusal (flow-value-envelope.ts) recognises the spec refusal of a blank expression by asking the spec once, and both the value cell and the Problems row say 'This value needs an expression. Write one, or switch the value back to text.' (studio i18n en/zh). No client validator added; no spec change.",
      "tests": "head 7c47a855, all under os-verify-lock. New AutomationsPillar.problemsAgree-27799.test.tsx: 3 passed (one-judge pin: flow parse passes, publish verdict messages == valueEnvelopeRefusal(blank); cell + Problems row both show the business sentence, target names node 'write' and config.fields.id, tab count 1; control: writing record.id clears both after the autosave). Updated FlowKeyValueField.valueEnvelope.test.tsx blank case to the business sentence. app-shell type-check exit 0. vitest over studio-design/ + 91 named flow/inspector/problems files: Test Files 357 passed (357), Tests 3097 passed. packages/i18n/: 90 files passed, 1380 tests passed, 13 skipped. Ablations via scripts/ablation-replace.mjs, each restored (blob == HEAD, git diff HEAD empty): preview diagnostics wiring -> 2 of 3 new cases red; Problems-row wording -> 1 red; value-cell wording -> 2 red. app-shell tests import src, so no dist rebuild leg.",
      "gates": "dispatch-gates --commands at 7c47a855: 34 derived; each run, exit recorded before any pipe; all exit 0 (incl. node scripts/check-sdui-manifest.mjs and pnpm --dir ui exec vitest run scripts/ run alone under the lock: 169 passed, 2 skipped files). --ran: 34 derived, 34 run, 0 NOT-MEASURED, 0 UNRUN. Outside derivation: pnpm check:new-line-citations (ui) exit 0. CI families: PR #27826 check-runs, not yet concluded at report time.",
      "line_budget": "12 files changed: 9 source/i18n/changeset + 1 new test + 1 updated test; well under 3000 changed lines",
      "files_changed": [
        ".changeset/studio-flow-problems-read-publish-verdict.md",
        "ui/packages/app-shell/src/views/metadata-admin/draftVerdict.ts",
        "ui/packages/app-shell/src/views/metadata-admin/inspectors/FlowKeyValueField.tsx",
        "ui/packages/app-shell/src/views/metadata-admin/inspectors/FlowKeyValueField.valueEnvelope.test.tsx",
        "ui/packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeConfigField.tsx",
        "ui/packages/app-shell/src/views/metadata-admin/inspectors/flow-value-envelope.ts",
        "ui/packages/app-shell/src/views/metadata-admin/previews/ProblemsPanel.tsx",
        "ui/packages/app-shell/src/views/metadata-admin/previews/flow-problems.ts",
        "ui/packages/app-shell/src/views/studio-design/AutomationsPillar.problemsAgree-27799.test.tsx",
        "ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx",
        "ui/packages/i18n/src/namespaces/studio/en.ts",
        "ui/packages/i18n/src/namespaces/studio/zh.ts"
      ],
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 — POST /repos/objectstack-ai/objectstack/dispatches (fleet-write pr_create #27826, draft, no labels, no assignees, no review request: the harness after-PR assign/review step was skipped per the dispatch order); this report comment via post-stamped. git push is not a REST write.",
      "deviations": [
        "PR body order: the dispatch put the maintainer brief before Fixes; os-dev.md (wins) puts Fixes and the declaration lines right after the attribution and the brief after them. Followed os-dev.md.",
        "Commit trailer: the model-free pair per AGENTS.md, not the harness's model-named Co-Authored-By.",
        "Repro measured in a component test with a faithful server double (real FlowSchema, real lint validateStackExpressions), not a browser walkthrough; the server path spelling (path ?? where, kept by itemRelativeIssuePath) is read from authoring-rules.ts and metadata-diagnostics.ts, not from a live server."
      ],
      "open_questions": [],
      "out_of_scope_findings": [
        "class: b (seam) · reach: public door — Studio Automations, Update Records value written as a blank expression: the draft read serves the expression-invalid finding at the where prose, so the Problems row (now listed) cannot select or reveal the node · Seam: lint:ExprIssue.path for flow node value slots → runtime:withPublishVerdict itemRelativeIssuePath → renderer:flow-problems serverTarget. ExprIssue.path is set only for a top-level edge condition and object validation condition/when; a flows[0].nodes[N].config.KEY.SUB path would be placed on the node by the existing mapping with no ui change · dedupe words: ExprIssue path flow node config value, expression-invalid where locator node, _diagnostics node value slot path",
        "carrier: #27521 — row 27's suggestion half (Triggering record target, object pre-fill, field pickers), out per the ruling"
      ]
    }

    Generated by Claude Code

  3. objectstack-fleet commented on Oct 30, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:ui#3 · os-bill · session_01Utp6CaJoinvGQSbHeDaWBe

    ACCEPT → PR #27826 comment 6512539542 · 2026-10-30T01:18Z


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions