windmill-labs/windmill · error
search requires a non-empty string.
Error message
search requires a non-empty string.
What it means
The diff-search tool searches across workspace diffs for a query string; it requires `args.search` to be a non-empty string and throws this error when it is missing or empty (`(args.search ?? '').length === 0`). Pure argument validation thrown before any diff units are collected.
Source
Thrown at frontend/src/lib/components/copilot/chat/global/core.ts:7105
}
}
// Literal substring search over the changed lines of every diff in the
// comparison. Materializes all patches first (search cannot skip any), then
// scans in memory — same output conventions as search_app.
async function diffSearch(
args: {
against?: 'deployed' | 'parent_workspace'
search?: string
file_glob?: string
max_matches?: number
},
ctx: WriteDraftCtx
): Promise<string> {
const { workspace, toolId, toolCallbacks } = ctx
const query = args.search ?? ''
if (query.length === 0) {
throw new Error('search requires a non-empty string.')
}
toolCallbacks.setToolStatus(toolId, { content: `Searching diffs for "${query}"...` })
const units: DiffSearchUnit[] = []
const failedPaths: string[] = []
let unflushedNote = ''
if (args.against === 'parent_workspace') {
const parent = forkParentOrThrow(workspace)
const index = await getForkDiffIndex(workspace, parent, { materializeAll: true })
if (index.skippedComparison) {
const message = forkComparisonUnavailableMessage(parent)
toolCallbacks.setToolStatus(toolId, { content: message })
return message
}
collectDiffSearchUnits(index.entries, units, failedPaths)
} else {
const { unflushedPaths } = await flushGlobalDraftSaves(workspace)
expireWorkspaceDiffList(workspace)View on GitHub (pinned to e474e8803c)
Solutions
- Retry with a non-empty `search` string
- To see all changes, use the diff tools per item instead of the search tool
Example fix
// before
searchDiffs({ search: '' })
// after
searchDiffs({ search: 'handle_error' }) Defensive patterns
Strategy: validation
Validate before calling
if (typeof args.search !== 'string' || args.search.length === 0) {
throw new Error('search requires a non-empty string')
} Type guard
function hasSearchQuery(args: { search?: string }): args is { search: string } {
return typeof args.search === 'string' && args.search.length > 0
} Try / catch
try {
return await searchDiffs(args)
} catch (e) {
if (String(e?.message).includes('search requires a non-empty string')) {
// ask the caller for a query, or fall back to per-item diffs
return promptForQuery() ?? listAllDiffs()
}
throw e
} Prevention
- Always supply a concrete query string to the diff-search tool
- Trim intended queries but reject empty results instead of sending ''
- Use per-item diff tools when you want an overview rather than a text search
When it happens
Trigger: Calling the search-diffs tool with `search` omitted, an empty string, or `search: undefined` — e.g. the agent intends a broad scan but sends no query.
Common situations: Template calls with unfilled search placeholders; agents passing null/empty after trimming logic of their own; confusing the search tool with a list-all-diffs capability that needs no query.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Missing required arguments: ${required.join(", ")}. Use -d '
- file only applies to multi-file apps; ${type} "${path}" diff
- Workspace "${workspace}" is not a fork — it has no parent wo
- path is required.
- file only applies to multi-file apps; ${entry.kind} "${path}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/c5b626bcd87b604a.
Report an issue: GitHub.