Skip to content

bug: CLI gortex call search_text returns count=0 for every query, including known-positive controls; widening with repo:"*" does not help #310

Description

@tiendungdev

Environment

  • gortex v0.60.0+dd3bb30, Windows 11 Pro (10.0.26200)
  • 1 tracked repo; daemon status shows search sqlite-fts5 docs=72707
    (so the text index exists and is populated)

Repro (100% reproducible here)

$ gortex call search_text --arg query="setupOutboxDispatcher" --arg limit=3
{"count": 0, "matches": [], "query": "setupOutboxDispatcher",
 "scope_note": "0 results within the active scope (repo:domain-manage) — widen with repo:\"*\" or pass an explicit repo:/project:"}

$ gortex call search_text --arg query="setupOutboxDispatcher" --arg repo="*" --arg limit=3
{"count": 0, ...}

$ gortex call search_text --arg query="CREATE TABLE" --arg repo="*" --arg limit=5
{"count": 0, ...}

Control facts:

  • search_symbols finds setupOutboxDispatcher instantly (it exists at
    services/domain-core/cmd/dispatcher/main.go:388).
  • git grep -c "CREATE TABLE" → 39 files under db/migrations alone.
  • FTS index reports 72,707 docs.

So this is not "term not indexed" — every query returns zero, and the
scope_note's suggested escape hatch (repo:"*") also returns zero, which
makes the note actively misleading.

Confirmed repro — broken even in SOLO mode on a fresh daemon

Isolated home, fresh store, ONE tracked repo of 3 files containing the
literal UNIQUE_LITERAL_ALPHA_7391 in an indexed .go file (verified via
search_symbols finding its enclosing function):

SOLO:            count: 0   scope_note: 0 results within the active scope (repo:repo-a) ...
MULTI (2 repos): count: 0
AFTER UNTRACK:   count: 0
repo="*":        count: 0

So this is not an artifact of our production daemon's history — the CLI
search_text path returns zero in the most basic configuration possible.
Note the scope resolves to repo:repo-a while solo-mode matches carry
unprefixed paths (see #309): if the scope filter compares
match-path prefixes against RepoAllow, every solo match fails the test.
repo:"*" also returning 0 suggests the wildcard from the scope_note hint is
taken as a literal repo name rather than a widen.

Why this matters more than a broken verb

Agents are told zero results might mean "does not exist". A search verb that
returns zero for everything — while suggesting a widen that doesn't work —
manufactures false "X does not exist" conclusions. (We caught it only by
running a known-positive control; that control discipline is not something
every agent does.)

Diagnostic clue (from reading internal/mcp/tools_search_text.go)

Matches flow through filterTextMatchesByPath(..., repoPrefixes) and then
filterTextMatchesByResolvedScope(matches, resolved). Combined with the
companion dual-identity issue (repo registered as name `` at one layer and
domain-manage at another), the likely failure is:

  • match paths are stamped with one identity (e.g. empty prefix, solo-repo
    form: services\...),
  • resolved.RepoAllow carries the other (domain-manage),
  • the scope filter drops every match → count=0,
  • and repo:"*" may not reach this session-bound resolver at all
    ("session-bound sessions may only name their own workspace").

Proposed fix

  1. In filterTextMatchesByResolvedScope, treat a match whose path resolves
    inside a repo allowed by RepoAllow as allowed regardless of which ID
    form the path carries
    (normalize both sides to absolute path or to one
    canonical prefix before comparing).
  2. When the post-filter count is zero but the pre-filter count was non-zero,
    say so in scope_note (e.g. "N matches were excluded by scope"), so a
    filter bug is distinguishable from a genuine miss.
  3. Add a regression test: solo-repo → track second repo → untrack → CLI
    search_text for a known literal must return >0.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions