Skip to content

Flag dead action/route references in dashboard header actions (ADR-0049 for references) #3367

Closed

Description

@os-zhuang

Summary

Dashboard header actions[] (and widget actionUrl) can reference actions or routes that do not exist. Nothing in os validate / os build flags them, so they ship as buttons that silently do nothing when clicked. This is the ADR-0049 "enforce-or-remove" principle applied to references rather than to properties.

Surfaced while reviewing a production app on 16.0.0-rc.1.

Repro

Dashboard header actions such as:

header: {
  actions: [
    { label: 'Export PDF', actionType: 'script', actionUrl: 'export_dashboard_pdf' },
    { label: 'New Deal',   actionType: 'modal',  actionUrl: 'create_opportunity' },
    { label: 'Forecast',   actionType: 'url',    actionUrl: '/reports/forecast' },
  ],
}
  • export_dashboard_pdf / create_opportunity are script / modal targets but no such action is defined anywhere in the stack.
  • /reports/forecast is a url target that matches no registered report/view/object route.

All of these pass os validate and os build; at runtime the buttons render and do nothing. Authoring a non-existent target is a false affordance — the exact failure mode ADR-0049 exists to prevent for metadata properties.

Proposed check

Add reference-integrity validation for action targets:

  • actionType: 'script' | 'modal' → error/warn unless actionUrl resolves to a defined action.
  • actionType: 'url' → warn unless the path resolves to a registered view / report / object route (in-app route shape).

Applies to dashboard header.actions[], widget actionUrl, and any other surface that references an action/route by id or path.

Acceptance criteria

  • A dashboard action referencing an undefined script/modal action fails validation with a message naming the dashboard, button label, and unresolved target.
  • A url action pointing at a non-existent in-app route is at least warned.
  • Valid references (defined action / real route) pass.
  • Fixture coverage for defined vs dangling targets.

Lower priority than the two runtime-crash cases, but closes the same "declared ≠ enforced" gap for references.


Related shift-left checks from the same 14.7 → 16 upgrade: #3365, #3366, #3367.

Activity

  1. self-assigned this
    on Jul 21, 2026
  2. added a commit that references this issue on Jul 23, 2026
    db160dd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions