Skip to content

[Bug]: fact_store search action fails with "no such column" error on hyphenated queries (FTS5 tokenization) #14024

@V01ee

Description

@V01ee

Context

Found while debugging agent behavior on my homelab ( Holographic provider active). The agent was issuing 4 sequential fact_store calls for single-fact lookups, all returning 0 results with no visible error. Dropped to direct sqlite3 queries against ~/.hermes/profiles/<profile>/memory_store.db to isolate the cause. All repros below were executed manually against my actual database.

This report was drafted with AI assistance, but every query/error in the reproduction section was verified live. Happy to provide the full diagnostic session output if useful.

Bug Description

The Holographic memory provider's fact_store(action="search", ...) raises a SQLite OperationalError: no such column: <N> when the query string contains a hyphenated token like pve-01, pihole-02, lxc-103, etc.

Root cause: the FTS5 virtual table is created without an explicit tokenizer, so it defaults to unicode61 which treats - as a separator. When the plugin passes the raw query string pve-01 directly to MATCH, FTS5's query parser interprets the hyphen as the column-restriction operator and tries to resolve 01 as a column name. Since no column named 01 exists, the query errors out with zero results.

This is particularly impactful for homelab/infrastructure users whose hostnames commonly follow <name>-<number> naming conventions.

Reproduction

Environment: Hermes Agent, Holographic memory provider active, any profile.

Create a fact with a hyphenated identifier, then try to search for it:

# Setup
fact_store(action="add",
    content="PVE-01 hardware: i5-13500T, IP 10.20.90.00",
    category="hardware", tags="pve-01,homelab")

# Fails
fact_store(action="search", query="pve-01")
# -> OperationalError: no such column: 01
# -> Returns 0 results

# Workarounds (all return the expected hit)
fact_store(action="search", query='"pve-01"')   # phrase-quoted
fact_store(action="search", query="pve 01")     # space-separated AND

Direct SQLite reproduction:

import sqlite3
c = sqlite3.connect("~/.hermes/profiles/<profile>/memory_store.db")

# These error:
c.execute("SELECT COUNT(*) FROM facts_fts WHERE facts_fts MATCH ?", ("pve-01",))
# sqlite3.OperationalError: no such column: 01

c.execute("SELECT COUNT(*) FROM facts_fts WHERE facts_fts MATCH ?", ("PVE-01",))
# sqlite3.OperationalError: no such column: 01

# These work:
c.execute("SELECT COUNT(*) FROM facts_fts WHERE facts_fts MATCH ?", ('"pve-01"',))
# -> returns hits

c.execute("SELECT COUNT(*) FROM facts_fts WHERE facts_fts MATCH ?", ("pve 01",))
# -> returns hits

Schema for reference

CREATE VIRTUAL TABLE facts_fts
    USING fts5(content, tags, content=facts, content_rowid=fact_id);

No tokenize= clause, so default unicode61 is used.

Impact

  • Silent retrieval failure — users don't see the error, they just get {"results": [], "count": 0} and assume the fact isn't there.
  • Agent LLMs compensate by issuing multiple alternative queries (observed: 4 sequential fact_store calls for a single lookup), burning tokens and latency.
  • Affects any deployment with hyphenated naming (homelab/infra, K8s resources, container names, Docker compose services, etc.).

Proposed fix (pick one)

Option A — Escape in plugin (minimally invasive, backward compatible):

In the fact_store search action, auto-wrap unquoted hyphenated tokens in double quotes before passing to FTS5:

import re

def sanitize_fts5_query(query: str) -> str:
    # Wrap bare hyphenated tokens in double quotes
    return re.sub(r'(?<!")(\b\w+(?:-\w+)+\b)(?!")', r'"\1"', query)

Option B — Change tokenizer (schema migration):

Recreate facts_fts with tokenize="unicode61 tokenchars '-_.'" so hyphens become part of tokens. Requires rebuilding the index for existing users.

Option A is backward-compatible and doesn't require migration. Option B gives better matching semantics long-term.

Workaround for users hitting this now

Update your retrieval protocol (in MEMORY.md or agent instructions) to always wrap hyphenated search terms in double quotes:

fact_store(action="search", query='"pve-01"')

Environment

  • Hermes Agent (main branch as of filing)
  • Holographic memory provider (plugins/memory/holographic)
  • Python 3.x, SQLite with FTS5 support
  • Tokenizer: default unicode61 (no tokenize= clause in CREATE VIRTUAL TABLE)

Related

  • Holographic plugin README lists fact_store search as a primary action but doesn't mention the hyphen limitation.
  • User-guide docs at /docs/user-guide/features/memory-providers similarly don't flag this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existstool/memoryMemory tool and memory providerstype/bugSomething isn't working

    Type

    No type
    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