Skip to content

fix: strip # prefix from tags in isTaskFile for tag-based identification#1607

Open
victoraraujo105 wants to merge 2 commits intocallumalpass:mainfrom
victor-software-house:fix/tag-identification-hash-prefix
Open

fix: strip # prefix from tags in isTaskFile for tag-based identification#1607
victoraraujo105 wants to merge 2 commits intocallumalpass:mainfrom
victor-software-house:fix/tag-identification-hash-prefix

Conversation

@victoraraujo105
Copy link

@victoraraujo105 victoraraujo105 commented Feb 15, 2026

Summary

  • isTaskFile fails to match tasks when using tag-based identification because Obsidian's metadata cache prepends # to frontmatter tag values
  • tags: [task] in YAML becomes ["#task"] in cache.frontmatter.tags, causing matchesHierarchicalTagExact("#task", "task") to return false
  • Fix: strip the # prefix before passing to matchesHierarchicalTagExact

Reproduction

  1. Set task identification to "tag" method with taskTag: "task" (the default at src/settings/defaults.ts:262)
  2. Create a task file with tags: [task] in frontmatter (either via the plugin UI or tn create)
  3. Run the following in the Obsidian developer console to observe the bug:
// Check what the metadata cache returns for tags
const file = app.vault.getMarkdownFiles().find(f => f.path.includes('TaskNotes/Tasks/'));
const cache = app.metadataCache.getFileCache(file);
console.log(cache.frontmatter.tags);
// Output: ["#task", ...] -- note the '#' prefix added by Obsidian

// Check what taskTag is set to
console.log(app.plugins.plugins['tasknotes'].settings.taskTag);
// Output: "task" -- no '#' prefix

// The comparison "#task" !== "task" always fails
  1. Observe that tn list returns 0 tasks despite files existing on disk:
# Create a task
tn create "Test task today #planning 15m"
# Output: Task created successfully!

# List tasks -- returns 0 because isTaskFile fails
tn list
# Output: Found 0 tasks
  1. After applying this fix, tn list correctly returns the created task.

Root cause

TaskManager.isTaskFile() at src/utils/TaskManager.ts:103 passes raw frontmatter.tags values (which include the # prefix from Obsidian's metadata cache) directly to FilterUtils.matchesHierarchicalTagExact(), which does an exact string comparison without accounting for the prefix.

Before fix:

return frontmatter.tags.some((tag: string) =>
    typeof tag === 'string' && FilterUtils.matchesHierarchicalTagExact(tag, this.taskTag)
);
// matchesHierarchicalTagExact("#task", "task") => false

After fix:

return frontmatter.tags.some((tag: string) => {
    if (typeof tag !== 'string') return false;
    const cleanTag = tag.startsWith('#') ? tag.slice(1) : tag;
    return FilterUtils.matchesHierarchicalTagExact(cleanTag, this.taskTag);
});
// matchesHierarchicalTagExact("task", "task") => true

Tests

Added 23 tests in tests/unit/utils/TaskManager.isTaskFile.test.ts covering:

  • Obsidian metadata cache tags (with # prefix) -- the primary bug scenario
  • Raw frontmatter tags (without # prefix) -- backward compatibility
  • Mixed tag formats -- both #-prefixed and plain tags in same array
  • Hierarchical tags -- #task/project matching task
  • Case insensitivity -- #Task matching task
  • Edge cases -- null/undefined frontmatter, non-array tags, non-string values, empty arrays, double-hash (##task), bare #

All 23 tests pass. No pre-existing tests were affected.

Test plan

  • isTaskFile returns true for tags: ["#task"] when taskTag is "task"
  • isTaskFile still works for tags without # prefix
  • Hierarchical tag matching works (e.g., #task/subtask matches task)
  • Case-insensitive matching works
  • Edge cases handled (null, undefined, non-string, empty)
  • Full test suite passes with no regressions (same 9 pre-existing failures on main)

Obsidian's metadata cache prepends '#' to frontmatter tag values
(e.g., tags: [task] becomes ["#task"] in cache.frontmatter.tags).
isTaskFile passes these raw values to matchesHierarchicalTagExact,
which compares "#task" against the taskTag setting value "task" and
fails to match.

Strip the '#' prefix before comparing so tag-based task identification
works correctly without requiring users to set taskTag to "#task".
Cover the fix for Obsidian metadata cache prepending '#' to
frontmatter tags. Tests verify both '#'-prefixed and plain tags,
hierarchical tags, case insensitivity, mixed formats, and edge cases.
@victoraraujo105 victoraraujo105 force-pushed the fix/tag-identification-hash-prefix branch from b33dec1 to 7e4261c Compare February 15, 2026 20:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant