rohitg00/agentmemory · error

query must be a non-empty string

Error message

query must be a non-empty string

What it means

The mem::expand-query iii function validates its payload before doing work: if data is missing, query is not a string, or query is empty/whitespace, it logs a warning and returns { success: false, error: 'query must be a non-empty string' } rather than throwing. Callers (e.g. MCP tool handlers) receive this structured failure result and must surface it.

Source

Thrown at src/functions/query-expansion.ts:76

    entityExtractions.push(match[1].trim());
  }

  return {
    original: "",
    reformulations,
    temporalConcretizations,
    entityExtractions,
  };
}

export function registerQueryExpansionFunction(
  sdk: ISdk,
  provider: MemoryProvider,
): void {
  sdk.registerFunction("mem::expand-query", 
    async (data: { query: string; maxReformulations?: number } | undefined) => {
      if (!data || typeof data.query !== "string" || !data.query.trim()) {
        logger.warn("Invalid expand-query payload");
        return { success: false, error: "query must be a non-empty string" };
      }
      const rawMaxR = Number(data.maxReformulations);
      const maxR = Number.isFinite(rawMaxR)
        ? Math.max(1, Math.min(10, Math.floor(rawMaxR)))
        : 5;
      const query = data.query.trim();

      try {
        const response = await provider.compress(
          QUERY_EXPANSION_SYSTEM,
          `Expand this query for memory retrieval:\n\n"${query}"`,
        );

        const parsed = parseExpansionXml(response);
        if (!parsed) {
          logger.warn("Failed to parse query expansion");
          return {

View on GitHub (pinned to e04ba88819)

Solutions

  1. Ensure the payload is { query: "<non-empty string>" } and that the argument is actually bound (log it before triggering).
  2. Fix the calling handler to validate args.query with typeof checks before sdk.trigger, per the MCP-handler pattern.
  3. Check the tool/argument name on the client side hasn't changed (e.g. query vs q).
  4. Handle the { success: false } result in the caller instead of assuming success.

Example fix

// before
await sdk.trigger({ function_id: "mem::expand-query", payload: { q: text } });
// after
if (typeof text !== "string" || !text.trim()) throw new Error("query required");
await sdk.trigger({ function_id: "mem::expand-query", payload: { query: text } });
Defensive patterns

Strategy: validation

Validate before calling

function buildExpandQueryPayload(args: Record<string, unknown>) {
  const query = typeof args["query"] === "string" ? args["query"] : "";
  if (!query.trim()) throw new Error("query must be a non-empty string");
  return { query, maxReformulations: 5 };
}

Type guard

const isExpandQueryPayload = (d: unknown): d is { query: string; maxReformulations?: number } =>
  typeof d === "object" && d !== null &&
  typeof (d as any).query === "string" && (d as any).query.trim().length > 0;

Try / catch

const res = await sdk.trigger({ function_id: "mem::expand-query", payload });
if (!res.success) {
  console.error(`expand-query rejected: ${res.error}`);
}

Prevention

When it happens

Trigger: Calling sdk.trigger({ function_id: 'mem::expand-query' }) with payload undefined, { query: 123 }, { query: "" }, or { query: " " }, or a handler that forwards an unvalidated/missing query argument.

Common situations: An MCP client sends a memory_expand_query tool call without the query argument; a handler passes raw request body through without whitelisting/typing; a refactor renamed the field so query is undefined at runtime.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of rohitg00/agentmemory@e04ba88819 (2026-08-30). Data as JSON: /api/errors/217fd1a7d1a7eacc. Report an issue: GitHub.