Unexpected Behavior from “Does Not Contain” Filter

Steps to reproduce

  1. Create five files, file1, file2, file3, file4, and file5
  2. Give them all the property project: "myproject”
  3. Give file1 the tag mytag
  4. Give file2 the tag archive
  5. Set up file3 with an empty tag property, like this: tags:
  6. Set up file4 with an empty tag property, like this: tags: []
  7. file5 should have no tag property at all.
  8. Create a Base with two filters: project → is → myproject and tags → does not contain → archive

Expected result

I expect all files to be included in the base, except for file2 because it has the archive tag.

Actual result

Only file1 and file4 are included in the base. I understand if excluding file5 is intended behavior. but I’m surprised to see file3 handled differently than file4, since they’re both considered “Empty” when viewing in Live Preview mode.

Environment

SYSTEM INFO:
Obsidian version: v1.9.2
Installer version: v1.7.4
Operating system: Darwin Kernel Version 24.5.0: Tue Apr 22 19:52:00 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6031 24.5.0
Login status: logged in
Language: en
Catalyst license: supporter
Insider build toggle: on
Live preview: on
Base theme: adapt to system
Community theme: Minimal v7.7.19
Snippets enabled: 4
Restricted mode: on

2 Likes

Whether this will help or not, I suggest you download and reinstall Obsidian. You have an old installer, and you likely want to be on at least 1.8.9.

1 Like

From my various tests :smile: : the tags key in file3 :

---
tags: 
---

… corresponds to null.

While the tags key in file4:

---
tags:  []
---

… corresponds to blank.

So while they both appear as Empty in Properties in Live Preview, they’re actually not the same underneath.

The difference can be seen when you search for the tags property :blush:

You could try to play around with an is empty condition :blush: (which I think handles both null and blank values now … but I think it also returns files where the key doesn’t exist so you might need to filter out the unwanted files using something like: note.keys().contains("tags"))

This could also be useful: Bases Migration/Quick Start Guide

Thanks, we will think about this.

Steps to reproduce

  1. Create a note named Test1.md containing a List property named ListProperty, and enter a link to that note in the ListProperty, i.e. [[Test]]

  2. Create a note named Test2.md and set its ListProperty to anything else (e.g. xxx or [[Test2]])

  3. Create a base with the filter ‘ListProperty contains [[Test1]]’

Result: As expected, Test1 is listed in the results and Test2 is not.

  1. Now set the ListProperty in Test1 to Empty (or remove the property altogether from the note).

Result: As expected, Test1 is no longer listed in the base’s filter results.

  1. Now change the base’s filter to ListProperty does not contain [[Test1]]

Results:
Test2 is correctly listed in the results.
Test1 is incorrectly excluded from the results.

More generally:
Only notes with a non-empty ListProperty (that isn’t [[Test1]]) are shown in the results. I would expect notes with an empty ListProperty also to be returned.

Did you follow the troubleshooting guide?

Yes

Expected result

Described in the ‘Steps to Reproduce’ section.

Actual result

Described in the ‘Steps to Reproduce’ section.

Environment

SYSTEM INFO:
Obsidian version: v1.9.12
Installer version: v1.9.10
Operating system: Darwin Kernel Version 24.6.0: Mon Jul 14 11:30:40 PDT 2025; root:xnu-11417.140.69~1/RELEASE_ARM64_T6041 24.6.0
Login status: logged in
Language: en
Catalyst license: supporter
Insider build toggle: off
Live preview: on
Base theme: adapt to system
Community theme: none
Snippets enabled: 0
Restricted mode: on

RECOMMENDATIONS:
none


Additional information

  • The problem only occurs with [[WikiLink]] entries in List-type properties. Plain-text entries work as expected.

  • The same bug also exists with ‘does not contain any of’ filters.

Created a visual example of the issue with three notes:

Filtering the test property to contain the item value matches the one note that fits that condition:

Filtering the test property to not container the item value matches one note that fits that condition, but does not match Third Note due to its test property being empty.

From my PoV this is not intuitive as the negation of the contains query should be that, a negation. Instead there is an overlap in behaviour that is present in both contains and does not contain.
I would expect a contains condition to split the set into two sets, set A with all notes that fulfill the condition and set B with all notes that do not. And the does not contain should therefore be set B. Instead there is a hidden set C of notes where the property is empty, and set C is just excluded from that both conditions.

Additionally, it is already possible to filter for notes with a non-empty property using the is not empty condition, so filtering for notes that do not contain a property but have property values is still possible even when the hidden feature is removed.
And it becomes possible to search for notes that truly do not contain a specific property [without having to resort to a formula property].

In programmer speak, arrayOfArbitraryStrings.filter(entry => entry.includes(matchString) and arrayOfArbitraryStrings.filter(entry => entry != '' && !entry.includes(matchString) aren’t negations of each other, but are presented as such.

Ran into this today and was direceted by the community to this issue. Would love to have this addressed in future release!