Skip to content

Console: modal-typed actions resolve target as an object — submit fails with GET /meta/object/<target> 400 #3530

Description

@os-zhuang

Summary

Submitting a type: 'modal' action fails with "Error loading form — Bad Request". The Console resolves the action's target as an object name and issues GET /api/v1/meta/object/<target>, which 400s because target names a page, not an object.

Per the spec, that is the wrong lookup:

type: 'modal' — target is required (the modal/page name to open).
— @objectstack/spec/dist/action.zod-*.d.ts, Action target docs

Environment

Steps to reproduce

  1. Declare a modal action and a matching page:
export const LogCallAction: Action = {
  name: 'log_call',
  label: 'Log a Call',
  type: 'modal',
  target: 'log_call',            // ← the modal PAGE name, per spec
  body: { language: 'js', source: `/* insert a record */`, capabilities: ['api.write'] },
  locations: ['record_header'],
  params: [
    { name: 'subject',  label: 'Call Subject',       type: 'text',     required: true },
    { name: 'duration', label: 'Duration (minutes)', type: 'number',   required: true },
    { name: 'notes',    label: 'Call Notes',         type: 'textarea' },
  ],
};

// registered page
export const LogCallPage: Page = { name: 'log_call', type: 'utility', /* … */ };
  1. Open a record, click Log a Call.
  2. The modal opens and the params form renders correctly from params.
  3. Fill it in, press 确认 / Confirm.

Expected

The action body executes with the collected input, and the record is written.

Actual

The modal body is replaced with:

Error loading form
Bad Request

Network:

GET /api/v1/meta/object/log_call → 400 Bad Request

The body never runs; nothing is written.

Scope

Reproduced on every modal action in the app — log_call, log_meeting, create_campaign, escalate_case, close_case, mass_update_stage, send_email. A freshly authored one fails identically (GET /api/v1/meta/object/schedule_followup → 400), so it is not about any particular page definition.

The params form rendering correctly but the submit path resolving target differently suggests two code paths that disagree about what target means: the render path treats it as a page (correct), the submit path as an object.

Impact

Modal actions are the natural shape for "collect a couple of fields and write something" — the most common custom action in a business app. None of them can be completed. The only workaround we found is to re-author each one as a type: 'flow' screen flow.

Related

Screen flows are also un-completable from the Console (Submit never calls the resume endpoint) — filed separately. Together these make every interactive custom action in the app non-functional.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions