# Swift Predicate: Incorrect(?) Fatal Error on KeyPath With Multiple Components

**URL:** <https://forums.swift.org/t/swift-predicate-incorrect-fatal-error-on-keypath-with-multiple-components/76982>\
**Category:** Using Swift\
**Tags:** macros, predicate\
**Created:** [January 4, 2025, 12:18am UTC](https://forums.swift.org/t/swift-predicate-incorrect-fatal-error-on-keypath-with-multiple-components/76982 "2025-01-04T00:18:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![bdkjones](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bdkjones/32/13872_2.png) [@bdkjones](https://forums.swift.org/u/bdkjones)\
**Post date:** [January 4, 2025, 12:18am UTC](https://forums.swift.org/t/swift-predicate-incorrect-fatal-error-on-keypath-with-multiple-components/76982/1 "2025-01-04T00:18:20Z")

</div>

# Context

I'm attempting to create a Swift Predicate using the `#Predicate` macro as shown here:

```swift
final class Foo 
{
    var title: String = ""
    var name: String = ""
}

let p = #Predicate<Foo> { $0.title == "test" }

```

This compiles fine, but at runtime crashes with this:

> Foundation/KeyPath+Inspection.swift:65: Fatal error: Predicate does not support keypaths with multiple components

Here's what the macro expands to, according to Xcode:

```swift
Foundation.Predicate<Foo>({
    PredicateExpressions.build_Equal(
        lhs: PredicateExpressions.build_KeyPath(
            root: PredicateExpressions.build_Arg($0),
            keyPath: \.title
        ),
        rhs: PredicateExpressions.build_Arg("test")
    )
})

```

# Question

Why? I've seen some discussion threads where this error message pops up when an optional is involved in a KeyPath, but that's not the case here. And there's not multiple components. This is essentially the simplest possible Predicate, lifted straight out of the example in the documentation, and it crashes at runtime. I'm a little mystified.

# Details

- Swift Language Version: 6
- Xcode Version: 16.2
- Deployment Target: macOS 15.2
- This is a brand-new Xcode Project. I added the `Foo` class and then one single line in `-applicationDidFinishLaunching()` to construct the Predicate.
- Stack trace:

 ![Screenshot 2025-01-03 at 16.16.18](https://global.discourse-cdn.com/swift/original/3X/3/0/3037e78fcefa2bcb58eace4c586d1c43409f3754.jpeg)

# NB:

I'm not sure if this is technically a "Swift Language" issue or a Foundation issue, but I've asked the question in more general places (SO) and gotten nothing. Swift Predicates are pretty new, the documentation is very sparse, and I'm hoping the Swift Forums have more expertise.

---

<div class="post-metadata">

**Author:** ![ibex](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ibex/32/30439_2.png) [@ibex](https://forums.swift.org/u/ibex)\
**Post date:** [January 4, 2025, 1:26am UTC](https://forums.swift.org/t/swift-predicate-incorrect-fatal-error-on-keypath-with-multiple-components/76982/2 "2025-01-04T01:26:37Z")

</div>

> [@bdkjones](#):
>
> ```swift
> final class Foo 
> {
> var title: String = ""
> var name: String = ""
> }
> 
> let p = #Predicate<Foo> { $0.title == "test" }
> 
> ```

Don't know why, but this (`class` --\> `struct`) doesn't crash:

```swift
struct Foo {
    var title: String = ""
    var name: String = ""
}

let p = #Predicate<Foo> { $0.title == "test" }
print ("-->", p)

```

Prints

```swift
--> capture1 (Swift.String): "test"
Predicate<AsyncStreamExplorer.C.(unknown context at $100005dec).(unknown context at $100005df8).Foo> { input1 in
    input1.title == capture1
}

```

---

<div class="post-metadata">

**Author:** ![bdkjones](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bdkjones/32/13872_2.png) [@bdkjones](https://forums.swift.org/u/bdkjones)\
**Post date:** [January 4, 2025, 4:34am UTC](https://forums.swift.org/t/swift-predicate-incorrect-fatal-error-on-keypath-with-multiple-components/76982/3 "2025-01-04T04:34:36Z")

</div>

Dear God, it's the `final` keyword.

You're correct: a `struct` worked just fine. So I started playing around with inheriting from `NSObject`, confirming to @Model (because I have other apps that use Predicates on SwiftData classes and those work just fine) and then finally, for no reason at all, I removed the `final` keyword. When I removed that, it worked. No other changes needed.

That _has_ to be a bug, right? At the very least, if Predicates can't work with `final` classes, the error message being displayed (keypaths with multiple components) is entirely misleading.

---

<div class="post-metadata">

**Author:** ![bdkjones](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bdkjones/32/13872_2.png) [@bdkjones](https://forums.swift.org/u/bdkjones)\
**Post date:** [January 4, 2025, 5:00am UTC](https://forums.swift.org/t/swift-predicate-incorrect-fatal-error-on-keypath-with-multiple-components/76982/4 "2025-01-04T05:00:47Z")

</div>

I get the feeling that `Predicate` was really only tested in the context of SwiftData, because this works just fine:

```swift
@Model
final class Foo
{
    var title: String = ""
}

let p = #Predicate<Foo> { $0.title == "test" } // Works

```

But this crashes:

```swift
final class Foo
{
    var title: String = ""
}

let p = #Predicate<Foo> { $0.title == "test" } // Crashes

```

All `@Model` really does is rewrite the class into fancy computed properties, so I gave this a shot and found that it also works just fine:

```swift
final class Foo
{
    var title: String {
        return ""
    }
}

let p = #Predicate<Foo>{ $0.title == "test" } // No problem.

```

The docs for `Predicate` make no mention about a failure to work with static dispatch. Apparently this is one more footgun to add to the long list of ways to hurt yourself with `Predicate` --\> [https://www.hackingwithswift.com/quick-start/swiftdata/how-to-filter-swiftdata-results-with-predicates](https://www.hackingwithswift.com/quick-start/swiftdata/how-to-filter-swiftdata-results-with-predicates)
