can1357/oh-my-pi · error · ToolError
`pat` must be a non-empty pattern
Error message
`pat` must be a non-empty pattern
What it means
The ast-grep tool requires a search pattern. The tool trims `params.pat` and throws this ToolError when the result is empty, because running ast-grep with no pattern is meaningless. It guards against the agent or caller passing whitespace-only or missing patterns.
Source
Thrown at packages/coding-agent/src/tools/ast-grep.ts:201
caption: "Loosest existence check for a symbol in one file",
call: { pat: "processItems", path: "src/worker.ts" },
},
];
readonly loadMode = "discoverable";
constructor(private readonly session: ToolSession) {}
async execute(
_toolCallId: string,
params: typeof astGrepSchema.infer,
signal?: AbortSignal,
_onUpdate?: AgentToolUpdateCallback<AstGrepToolDetails>,
_context?: AgentToolContext,
): Promise<AgentToolResult<AstGrepToolDetails>> {
return untilAborted(signal, async () => {
const pattern = params.pat.trim();
if (pattern.length === 0) {
throw new ToolError("`pat` must be a non-empty pattern");
}
const patterns = [pattern];
const skip = params.skip === undefined ? 0 : Math.floor(params.skip);
if (!Number.isFinite(skip) || skip < 0) {
throw new ToolError("skip must be a non-negative number");
}
const scopedPaths = toPathList(params.path);
const rawPaths = scopedPaths.length > 0 ? scopedPaths : ["."];
const scope = await resolveToolSearchScope({
rawPaths,
cwd: this.session.cwd,
internalUrlAction: "search",
settings: this.session.settings,
signal,
sessionFile: this.session.getSessionFile() ?? undefined,
localProtocolOptions: this.session.localProtocolOptions,
skills: this.session.skills,
resolveExternalUrl: async rawPath => {View on GitHub (pinned to 9690622007)
Solutions
- Supply a non-empty ast-grep pattern in `pat` (e.g. "$A === $B").
- Trim/validate the pattern client-side before invoking the tool and skip the call if empty.
- Ensure the tool schema marks `pat` as required so the model cannot omit it.
Example fix
// before
await tool.execute({ pat: "" }, ctx);
// after
const pat = "console.log($MSG)";
if (pat.trim()) await tool.execute({ pat }, ctx); Defensive patterns
Strategy: validation
Validate before calling
const pat = (params.pat ?? "").trim();
if (pat.length === 0) throw new Error("ast-grep pattern required before calling tool");
await tool.execute({ ...params, pat }, ctx); Try / catch
try {
await tool.execute({ pat }, ctx);
} catch (e) {
if (e instanceof ToolError && e.message.includes("non-empty pattern")) {
// surface a fix-hint to the caller / re-prompt with a pattern
} else throw e;
} Prevention
- Make `pat` a required field in the tool schema exposed to the model.
- Trim and check patterns before every ast-grep call.
- Log empty-pattern attempts to spot prompt/schema gaps.
When it happens
Trigger: Calling AstGrepTool.execute with params.pat undefined, an empty string (""), or a string of only whitespace (e.g. " ").
Common situations: An LLM agent emits an empty `pat` argument when the pattern is optional in its schema; a pipeline passes a user-supplied pattern after trimming it to nothing; a template fills `pat` from a variable that was never set.
Related errors
- objective is required when op=create
- token_budget must be a positive integer when provided
- skip must be a non-negative number
- Empty report. ${reportIssueDeviceUsage()}
- Invalid report format. ${reportIssueDeviceUsage()}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/da19605cb14b8a8e.
Report an issue: GitHub.