Skip to content

iOS capability sync strips Push Notifications "Broadcast" sub-feature (PUSH_NOTIFICATION_FEATURE_BROADCAST) every build #3815

Description

@exception

Build/Submit summary

iOS capability syncing disables the "Broadcast" sub-feature of Push Notifications on every eas build, because Broadcast is not a standalone capability — it's a setting nested under PUSH_NOTIFICATIONS (PUSH_NOTIFICATION_FEATURES → PUSH_NOTIFICATION_FEATURE_BROADCAST). The syncer's push patch only sends { capabilityType: 'PUSH_NOTIFICATIONS', option: 'ON' } (no sub-options), so it re-creates the Push Notifications capability at its defaults and drops the Broadcast flag.

Broadcast push is required for iOS 18 Live Activity broadcast push channels. After every build, creating a channel via the APNs channel-management API returns 400 BroadcastFeatureNotEnabled, until you re-enable Broadcast by hand in the Developer portal — only for the next build to strip it again.

Environment

  • eas-cli 19.1.0 (darwin-arm64, node 24.15.0)
  • iOS, EAS-managed credentials

Steps to reproduce

  1. In the Apple Developer portal, enable Broadcast under Push Notifications for your App ID (Identifiers → App ID → Push Notifications → Broadcast → Save). Required for iOS 18 broadcast push / Live Activity channels.
  2. Run eas build -p ios with managed credentials.
  3. Capability sync re-patches Push Notifications, dropping the Broadcast sub-feature.
  4. A backend POST /1/apps/{bundleId}/channels to APNs now returns 400 {"reason":"BroadcastFeatureNotEnabled"}.

Evidence (EAS_DEBUG=1)

The remote capability shows Broadcast as a nested setting under Push Notifications:

{
  "id": "<APPID>_PUSH_NOTIFICATIONS",
  "attributes": {
    "settings": [
      {
        "key": "PUSH_NOTIFICATION_FEATURES",
        "options": [
          { "key": "PUSH_NOTIFICATION_FEATURE_BROADCAST", "properties": [null] }
        ]
      }
    ],
    "enabled": true
  }
}

The sync decision + patch:

Will enable remote capability: aps-environment (Push Notifications).
Will skip remote capability: com.apple.security.application-groups (App Groups).
Will skip remote capability: com.apple.developer.associated-domains (Associated Domains).
Existing to disable:  [ '<APPID>_IN_APP_PURCHASE', '<APPID>_PUSH_NOTIFICATIONS' ]
Patch Request: [ { capabilityType: 'PUSH_NOTIFICATIONS', option: 'ON' } ]

The patch re-enables Push Notifications with default settings, so the PUSH_NOTIFICATION_FEATURE_BROADCAST sub-setting is lost. (It also lists IN_APP_PURCHASE to disable — the same reconciliation can strip other portal-only capabilities the syncer doesn't model.)

Why there is no config-level workaround

  • Broadcast has no entitlement, so it can't be declared in ios.entitlements for the syncer to preserve.
  • The capability is an App-ID-level setting in App Store Connect, not part of the build, so a config plugin can't set it.
  • The push patch has no field for sub-options.

Current workaround

EXPO_NO_CAPABILITY_SYNC=1 disables capability syncing entirely, preserving the manually-enabled Broadcast setting (and other portal-only capabilities like In-App Purchase).

It must be set in the shell environment — e.g. EXPO_NO_CAPABILITY_SYNC=1 eas build …, or exported in your shell. Setting it under a build profile's env in eas.json does not work: capability sync runs locally during credential resolution, before/outside the build-profile env (and eas credentials uses no build profile at all), so it never sees the eas.json value.

Request

One of:

  • Preserve capability sub-settings (e.g. PUSH_NOTIFICATION_FEATURE_BROADCAST) during sync rather than resetting Push Notifications to defaults; or
  • Don't disable/reset capabilities (or sub-features) the syncer doesn't model — treat them like the already-skipped App Groups / Associated Domains; or
  • At minimum, document that enabling Broadcast push requires EXPO_NO_CAPABILITY_SYNC=1 (or local credentials).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions