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

  1. Supply a non-empty ast-grep pattern in `pat` (e.g. "$A === $B").
  2. Trim/validate the pattern client-side before invoking the tool and skip the call if empty.
  3. 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

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


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/da19605cb14b8a8e. Report an issue: GitHub.