Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

console: a bulk action's lookup param bound through objectOverride renders as a free textbox — HotCRM's bulk 'Add to campaign' takes the campaign name as text, reports success, and writes orphan members #12207

Closed as duplicate

Description

@hotlong

Filing gate ①: a product defect, reproduced and measured. Source: 2026-10-12 hosted-shape browser pass of HotCRM 4.0.1 on a cloud rig at production v1.36.0's pins (objectui d758f2f20d, framework 56bf27affb).

What happens

HotCRM's lead action 加入营销活动 (crm_lead.create_campaign, locations: [list_toolbar, list_item]) declares one param that is bound to a lookup field on another object:

{"field":"crm_campaign","objectOverride":"crm_campaign_member","label":"营销活动","required":true}
  • Single-record dialog (row menu): the param renders as a lookup picker, and the action works.
  • Bulk dialog (select 1–2 rows → bulk bar → 加入营销活动): the same param renders as a plain textbox.
    • The tester typed the campaign's name (T-hc-sales-Campaign A, then its code CPG-0008). The confirm step listed raw record ids.
    • 执行 reported "成功 2 / 2" (then "成功 1 / 1").
  • What the server did with it (POST /api/v1/actions/crm_lead/create_campaign body {"recordId":"…","params":{"crm_campaign":"T-hc-sales-Campaign A"}} → 200):
    • Answered {"campaignId":"T-hc-sales-Campaign A","count":1,"ids":["KlpjuftuQyw7uWBo"]}, i.e. it stored the typed text as the campaign id.
    • The leads did not join the real campaign. The returned member ids read back as 404.
    • The orphan rows keep breaking hooks afterwards. Server log: campaign_member_metrics_refresh and campaign_lead_conversion_refresh → Record T-hc-sales-Campaign A not found in crm_campaign / Record CPG-0008 not found.

Reproduced 2 of 2.

Three layers, each with its own gap (for triage to split)

  1. objectui (this card): the bulk dialog does not resolve a field-bound param through objectOverride, so a lookup becomes a free textbox. The single-record dialog resolves it.
  2. framework, to check: ADR-0104 D2's param contract enforces reference-id shape, yet a value with spaces passed for a lookup-bound param. Either enforcement does not resolve objectOverride, or it does not check that the reference resolves.
  3. hotcrm: the action body writes crm_campaign_member rows without checking that the campaign exists.

Acceptance

  1. The bulk dialog renders a field-bound lookup param (including objectOverride) with the same lookup picker as the single-record dialog.
  2. A value that names no campaign is refused before any row is written. Where layers 2 and 3 apply, file and track them on their own cards.

🤖 Generated with Claude Code

Activity

  1. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Oct 12, 2026
  2. hotlong commented on Oct 12, 2026

    @hotlong
    ContributorAuthor

    Closing as a duplicate of #12105, found by the dedupe the filing gate requires. I ran that search after filing, which is the wrong order.


    🤖 Generated with Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions