Skip to content

[Bug]: ctx_batch_execute.queries silently searches only batch output, not global index — API parameter name misleads #696

@matiasduartee

Description

@matiasduartee

Platform

Claude Code

context-mode version

1.0.151

Debug script output (REQUIRED)

{
  "context_mode": {
    "version": "1.0.151",
    "binary_path": "C:\\Users\\<user>\\AppData\\Roaming\\npm\\node_modules\\context-mode\\",
    "available_commands": ["doctor", "upgrade", "hook", "statusline"]
  },
  "runtime": {
    "node": "v25.9.0",
    "bun": "1.3.14",
    "npm": "11.12.1"
  },
  "os": {
    "platform": "Windows 11 Pro",
    "version": "10.0.26200",
    "arch": "x64"
  },
  "doctor_output": {
    "platform_detection": "Claude Code (high confidence)",
    "storage_sessions": "C:\\Users\\<user>\\.claude\\context-mode\\sessions",
    "performance": "FAST (Bun detected)",
    "language_coverage": "5/11 (45%) — javascript, shell, typescript, python, perl",
    "server_test": "PASS",
    "hooks_configured": ["PreToolUse", "SessionStart"],
    "fts5_sqlite": "PASS",
    "plugin_cache_integrity": "PASS"
  }
}

Exact prompt that triggered the bug (REQUIRED)

Pre-condition: at least one document is already indexed in the global
session store via ctx_index (any file or directory containing the word
"frontmatter" somewhere in its text).

Step 1 — confirm the global index has matches via ctx_search:
   ctx_search(query: "validação de frontmatter")
   → expected: ≥1 result returned

Step 2 — issue an identical search via ctx_batch_execute.queries:
   ctx_batch_execute(
     commands: [{ label: "noop", command: "echo none" }],
     queries: ["validação de frontmatter"]
   )
   → observed: "No matching sections found"
   → expected (based on parameter name): same hit as Step 1

Full error output (REQUIRED)

Tool: ctx_batch_execute
Input:
  {
    "commands": [{ "label": "noop", "command": "echo none" }],
    "queries": ["validação de frontmatter"]
  }
Output:
  Executed 1 commands (1 lines, 0.0KB). Indexed 1 sections. Searched 1 queries.

  ## validação de frontmatter → No matching sections found.

  > Tip: Results are scoped to this batch only. To search across all
  > indexed sources, use ctx_search(queries: [...]).

By contrast, the same query via ctx_search:
  Tool: ctx_search
  Input: { "query": "validação de frontmatter" }
  Output: 1+ matching sections from the global indexed corpus

The contradiction is not a runtime error — it's a silent semantic mismatch.
The tool's own tip confirms the scope: `queries` inside ctx_batch_execute
searches ONLY the output of the commands in that same batch, never the
persistent global index that ctx_index/ctx_search operate on.

Reproduced across 4 independent client/model combinations during a
multi-IDE comparison test on v1.0.146 AND v1.0.148 (Windows 11):

┌────────────────────────────────────┬──────────────────────────────────┐
│ Client                             │ batch hits vs sequential hits    │
├────────────────────────────────────┼──────────────────────────────────┤
│ Claude Code (Opus 4.7)             │ batch: 0 / sequential: 8         │
│ Codex CLI (GPT-5)                  │ batch: 0 / sequential: 8         │
│ Antigravity (Gemini 3.5 Flash)     │ batch: 0 / sequential: 8         │
│ Antigravity (Gemini 3.1 Pro)       │ batch: 0 / sequential: 8         │
└────────────────────────────────────┴──────────────────────────────────┘

Same 5 queries, same indexed corpus, identical mismatch in 4/4 runs.
v1.0.149 → v1.0.151 changelog confirms this code path was not touched,
so the behavior persists on the current latest.

Steps to reproduce (REQUIRED)

  1. Install / upgrade:
    npm install -g context-mode@1.0.151

  2. Configure MCP in any client (Claude Code example):
    claude mcp add --transport stdio --scope user context-mode -- bun x context-mode

  3. From the agent session, seed the global index with any file:
    ctx_index(path: "<path-to-any-markdown-file-mentioning-'frontmatter'>")

  4. Verify the global index responds:
    ctx_search(query: "validação de frontmatter")
    → expect ≥1 result

  5. Issue the same search inside ctx_batch_execute:
    ctx_batch_execute(
    commands: [{ label: "noop", command: "echo none" }],
    queries: ["validação de frontmatter"]
    )
    → observe "No matching sections found"
    → tip in output explicitly confirms: "Results are scoped to this batch only"

What have you tried to fix it?

  1. Verified across 4 client/model combinations on Windows 11 with v1.0.146,
    v1.0.148, and confirmed unchanged in the v1.0.149 → v1.0.151 changelog.
    Identical 0-hit result in all 4 batch runs vs 8-hit baseline via
    ctx_search. The behavior is server-side and consistent — not a client
    adapter issue.

  2. Read the tool's own response tip carefully:
    "Results are scoped to this batch only. To search across all indexed
    sources, use ctx_search(queries: [...])."
    This confirms the maintainer is aware the parameter has a counter-
    intuitive scope. The issue is that the parameter name (queries)
    gives no signal that its scope differs from the top-level ctx_search.

  3. Workaround currently in use: instead of ctx_batch_execute, call
    ctx_search(queries: [...]) which accepts an array and runs all queries
    against the global index in a single round-trip. Measured ~7× faster
    than sequential ctx_search calls (the original motivation for trying
    ctx_batch_execute). This works perfectly — the ctx_batch_execute path
    is functionally redundant for the array-of-queries use case.

  4. Investigation hints (from external reading):

    • ctx_batch_execute is genuinely useful for the OTHER half of its
      contract: batch SHELL command execution with shared timing/output
      aggregation.
    • The queries parameter inside it appears designed to search the
      just-produced command output (e.g. grep-after-shell pattern).
    • The naming collision between top-level queries (global) and
      batch-internal queries (local) is what trips users up.
  5. Impact observed in our multi-IDE benchmark: the 4 LLMs we tested all
    reached for ctx_batch_execute first when asked to "run the same 5
    searches via batch instead of sequentially" — none anticipated the
    scope shift. All 4 only recovered after reading the tip in the tool's
    response. The naming is materially confusing.

Expected behavior:

Either rename the parameter to signal local scope, OR add a scope
flag, OR add a schema-level note. Any of:

Option A — rename:
ctx_batch_execute({
commands: [...],
batch_local_queries: [...] // or output_queries / local_queries
})

Option B — explicit scope flag:
ctx_batch_execute({
commands: [...],
queries: [...],
query_scope: "batch" | "global" // default "batch" preserves
// current behavior
})

Option C — schema description fix only (lowest effort):
Update the tool's JSON-Schema description for queries to:
"Search queries executed against the output produced by THIS batch's
commands only. To search the global indexed corpus, use ctx_search."

Bonus consideration: the tip currently appears only AFTER a 0-hit
response. Surfacing the same warning in the schema description
prevents the agent from making the wrong call in the first place.

Proposed PR shape (happy to implement if approach is approved):

If Option C (schema-only) is preferred — trivial: edit the tool
definition string in the MCP server registration. ~5 LOC.

If Option B (scope flag) is preferred — opt-in query_scope param
defaulting to "batch" preserves backwards-compat. Branch in the
handler routes "global" to the same code path ctx_search uses. ~30 LOC.

Tests: add cases for (a) batch scope returns 0 on globally-indexed-only
content (current behavior), (b) global scope returns same as ctx_search
for identical queries, (c) schema description includes the scope warning.

Happy to PR against next — let me know which option fits your roadmap.

Pre-submission checklist

  • I have run the debug script and pasted the output above
  • I am using the latest version of context-mode
  • I have searched existing issues for duplicates
  • I have included steps to reproduce the issue

Operating System

macOS (Apple Silicon)

JS Runtime

Bun 1.3.14

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions