windmill-labs/windmill · warning

search_app requires a non-empty query.

Error message

search_app requires a non-empty query.

What it means

The search_app copilot tool in the AI chat's global mode refuses to run when the model supplies an empty `query` argument. The tool searches the contents of an app file, and an empty query would be meaningless. This is an argument-validation guard thrown before any work starts.

Source

Thrown at frontend/src/lib/components/copilot/chat/global/core.ts:5697

		return false
	}
}

type AppSearchMatch = { filePath: string; line: number; text: string }

async function searchApp(
	args: {
		path: string
		query: string
		file_glob?: string
		max_matches?: number
	},
	ctx: WriteDraftCtx
): Promise<string> {
	const { workspace, toolId, toolCallbacks } = ctx
	const query = args.query
	if (query.length === 0) {
		throw new Error('search_app requires a non-empty query.')
	}
	toolCallbacks.setToolStatus(toolId, {
		content: `Searching app "${args.path}" for "${query}"...`
	})

	const value = await loadAppValueForRead(args.path, workspace)
	const maxMatches = Math.min(
		args.max_matches ?? SEARCH_APP_DEFAULT_MAX_MATCHES,
		SEARCH_APP_MAX_MATCHES_CEILING
	)
	const contextLines = SEARCH_APP_CONTEXT_LINES
	const needle = query.toLowerCase()

	let files = collectSearchableAppFiles(value).sort((a, b) => a.filePath.localeCompare(b.filePath))
	if (args.file_glob) {
		files = files.filter((f) => appFileMatchesGlob(f.filePath, args.file_glob as string))
	}

View on GitHub (pinned to e474e8803c)

Solutions

  1. Re-issue the tool call with a non-empty query string describing what to search for in the app
  2. If building the call programmatically, check `query.trim().length > 0` before invoking
  3. Improve the model's system/tool prompt so it always supplies a query

Example fix

// before
search_app({ path: 'f/app_main', query: '' })
// after
search_app({ path: 'f/app_main', query: 'handleFormSubmit' })
Defensive patterns

Strategy: validation

Validate before calling

if (typeof args.query !== 'string' || args.query.trim().length === 0) {
  throw new Error('search_app requires a non-empty query.')
}

Type guard

function hasQuery(args: { query?: string }): args is { query: string } {
  return typeof args.query === 'string' && args.query.length > 0
}

Try / catch

try {
  await searchApp(args)
} catch (e) {
  if (e instanceof Error && e.message.includes('non-empty query')) {
    // retry with a corrected, non-empty query
  }
}

Prevention

When it happens

Trigger: The AI model calls the search_app tool with `args.query` set to "" (empty string), typically when it omits the query or fills it with an empty value while attempting to search an app at `args.path`.

Common situations: LLM tool-call hallucination or truncation drops the query field; a caller-built tool invocation constructs args programmatically and the query variable was empty; prompt instructions didn't make clear the query is mandatory.

Related errors


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/9dd60d230cd5f976. Report an issue: GitHub.