App Intents Not Appearing in Siri: A Diagnostic Checklist

App Intents Not Appearing in Siri: A Diagnostic Checklist

⚠️ Speculative Architecture & Preview: This article discusses future system iterations (e.g., iOS 27, Xcode 27) as conceptual planning and architectural design patterns. Technical details represent previews and proposals rather than finalized APIs.

App Intents Not Appearing in Siri: A Diagnostic Checklist

An App Intent that works perfectly in the Shortcuts app but is never offered by Siri is one of the most disorienting bugs in App Intents work, because there is no error to follow. The intent compiles, conforms to the right protocol, and executes correctly when invoked — it is simply invisible. This article provides a staged diagnostic for App Intents not appearing in Siri, and the central claim is that almost every case is one of three independent gates, and the reported symptom does not tell you which one failed.

The failure of intuition here is structural: developers treat “Siri support” as a single feature. It is actually a three-stage pipeline — capability, index, and relevance — and Siri offers an intent only when all three pass. Because each gate fails silently, the only way to make progress is to test them in order.

Key Takeaways

  • Capability, index, and relevance are independent gates. Passing one says nothing about the next.
  • Spotlight indexing is the gate teams skip. An unindexed AppEntity makes a perfectly valid intent invisible to Siri.
  • Indexing during cold start is unreliable. Donations made in didFinishLaunching are frequently dropped.
  • Test with a direct Siri invocation, not with a suggestion. Suggestions depend on relevance; a direct request exercises capability and index only.
  • The system does not report gate failures. Index and relevance state must be observed through Spotlight and your own logging.

The Three Gates

+----------------+     +----------------+     +----------------+
|   Capability   | --> |     Index      | --> |   Relevance    |
| schema + build |     | Spotlight /    |     | donations +    |
|                |     | App Entities   |     | user context   |
+----------------+     +----------------+     +----------------+
        |                      |                      |
   "works in Shortcuts"   "entity resolvable"    "Siri suggests it"

Figure 1: The three gates an intent must pass before Siri will offer it.

The diagnostic value of this model is that each gate has a distinct, observable test. Do not skip ahead.


Gate 1 — Capability

Test: Does the intent appear in the Shortcuts app and execute when run from there?

If the answer is no, this is a build and conformance problem, and no amount of indexing will help. The common causes:

  • The intent type does not conform to a concrete AppIntent subtype (OpenIntent, ShowInAppSearchResultsIntent, or a schema-backed protocol).
  • The intent is declared in the widget extension but not exposed to the app, or vice versa. Capabilities must be reachable from the main app’s AppIntentsPackage.
  • A required @Parameter has no AppEntity query, so the intent is treated as incomplete and omitted from the Shortcuts list.
// Developer Thoughts: A schema-backed intent is what makes Siri eligible to
// route a natural-language request. A plain AppIntent is Shortcuts-only.
struct ShowProjectIntent: AppIntent {
    static var title: LocalizedStringResource { "Show Project" }
    static var openAppWhenRun: Bool { true }

    @Parameter(title: "Project")
    var project: ProjectEntity

    func perform() async throws -> some IntentResult {
        AppState.shared.pendingRoute = .project(project.id)
        return .result()
    }
}

If Gate 1 passes, the intent is real. Move on — do not modify the schema yet.


Gate 2 — Index

Test: Is the AppEntity actually present in the system index?

Siri can only offer entities the system knows about. An intent whose parameter entity was never indexed is a valid intent with nothing to act on, and Siri will silently decline to offer it. This is the gate that most teams skip.

There are two ways to index entities: contribute them to Spotlight via CSSearchableItem / IndexedEntity, or donate an NSUserActivity that references the entity. Both must happen after the app is running — not during cold start.

import CoreSpotlight
import AppIntents

// Developer Thoughts: Indexing here, not in didFinishLaunching.
// Cold-start donations are commonly dropped before the index is ready.
func indexProjects(_ projects: [Project]) async {
    for project in projects {
        var entity = ProjectEntity(project)
        entity.spotlightAttributes = [
            "name": project.name
        ]
        try? await CSSearchableIndex.default().indexAppEntities([entity])
    }
}

Verify indexing independently of Siri:

import CoreSpotlight

func confirmIndexed(query: String) {
    let context = CSSearchableIndex.default()
    let request = CSSearchableItemAttributeSet(contentType: .content)
    context.fetchLastClientState { state, error in
        // A missing or stale client state after an index pass means the
        // write did not land; the entity is not in the index.
        print("clientState=\(String(describing: state)) error=\(String(describing: error))")
    }
}

If the index is empty, Siri is not the bug — indexing is. Fix Gate 2 and retest before touching relevance.


Gate 3 — Relevance

Test: After passing Gates 1 and 2, does Siri suggest the intent, or only execute it on a direct request?

This distinction matters because it isolates relevance as the remaining variable. A direct request (“Hey Siri, show project Alpha”) exercises capability and index. A suggestion exercises relevance. If direct requests work and suggestions do not, you have a relevance problem — and it is the least urgent of the three, because direct invocation already delivers user value.

Relevance is driven by RelevantEntities donations and usage signals. Donations older than the system’s rolling window do not count:

import AppIntents

func donateRelevance(for project: Project) async {
    let entity = ProjectEntity(project)
    try? await RelevantEntities.updateEntities([entity])
}

Donate relevance when the user actually engages with a project in-app — opening it, editing it, or returning to it. Bulk-donating every entity at launch is a common mistake: it floods the signal, and the system discounts all of it.


The Diagnostic Checklist

SymptomFailed gateFirst action
Intent missing from Shortcuts entirelyCapabilityCheck AppIntent conformance and AppIntentsPackage membership
Intent in Shortcuts, not executable by direct Siri requestIndexVerify CSSearchableIndex / NSUserActivity donations post-launch
Intent executes on direct request, never suggestedRelevanceAdd targeted RelevantEntities donations on real engagement
Worked yesterday, not todayRelevance or index evictionRe-donate; check for a donation that ran during cold start
Works in simulator, not on deviceIndexConfirm the extension is indexed on a real device; simulator indexing differs

The Verdict: Debug in Order, Not in Parallel

The reason this problem consumes so much engineering time is that teams debug the gate they can see. Relevance has the most knobs, so it attracts the most attention — while the actual failure is usually a missing index entry that no amount of relevance tuning will repair.

When to use this checklist

  • Immediately, on the first “Siri doesn’t see my intent” report. The ordered triage eliminates the most common cause (index) in minutes.
  • During migration from SiriKit, where the vocabulary translation is correct but the indexing pipeline is new.

When the checklist is not the issue

  • If the intent fails only after a specific app update, suspect a changed entity identifier rather than any of the three gates.
  • If the intent fails only for non-English locales, the problem is localized resource coverage, not the pipeline.

The Hidden Cost

  • Index and relevance are invisible state. Unlike capability, there is no compiler and no Shortcuts UI that reports them. You must build your own instrumentation and trust it.
  • Cold start is a trap. The single most common root cause is a donation that ran during didFinishLaunching and was silently discarded. This bug is intermittent, which makes it expensive to reproduce and easy to misattribute.

The verdict: when an App Intent is not in Siri, stop iterating on the schema. Verify the entity is indexed first — it is the gate that fails most often and the only one that produces no symptom other than the one you are already staring at.


References & Further Reading

Ready for more depth?

Master these concepts with our structured technical roadmap.

View Roadmap