JuliusBrussee/caveman · error · Error

caveman-code: neither rg nor grep is available

Error message

caveman-code: neither rg nor grep is available

What it means

The grep tool shells out to ripgrep (`rg`) and falls back to GNU grep when rg fails to spawn. If BOTH binaries fail to spawn (missing from PATH or not installed), this error is thrown. The library performs no in-JS text search, so search availability is entirely a host-environment property.

Source

Thrown at packages/agent/src/code.ts:286

    result: "inline",
    timeoutMs: READ_TIMEOUT_MS,
    async execute(input, signal) {
      const root = await workspaceRoot();
      const scope = input.path === undefined ? root : await contained(input.path);
      const relativeScope = scope === root ? "." : relative(root, scope);
      const ripgrep = [
        "--line-number", "--no-heading", "--color", "never",
        "--max-count", String(GREP_MAX_MATCHES),
        ...(input.glob === undefined ? [] : ["--glob", input.glob]),
        "--regexp", input.pattern, "--", relativeScope,
      ];
      let run = await runProcess("rg", ripgrep, root, READ_TIMEOUT_MS, signal);
      if (run.spawnFailed) {
        run = await runProcess("grep", [
          "-rnI", "-m", String(GREP_MAX_MATCHES), "-E", "-e", input.pattern, "--", relativeScope,
        ], root, READ_TIMEOUT_MS, signal);
      }
      if (run.spawnFailed) throw new Error("caveman-code: neither rg nor grep is available");
      const body = run.output.trim() === "" ? "no matches" : run.output;
      const text = capOutput(body, caps.grep);
      record(`grep:${input.pattern}`, text);
      return text;
    },
  });

  const bashTool = tool({
    name: "bash",
    description:
      "Run one shell command in the workspace and return its combined stdout and stderr. " +
      `Times out after ${BASH_TIMEOUT_MS} ms; output is capped at ${caps.bash} bytes.`,
    input: schema.object({
      command: schema.string(),
      timeoutMs: schema.optional(schema.integer()),
    }),
    effect: "external",
    result: "inline",

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Install ripgrep (e.g. `apt-get install -y ripgrep` or `cargo install ripgrep`) in the environment the agent runs in — it is the preferred backend
  2. If rg cannot be shipped, ensure GNU grep exists at a PATH location visible to the agent process (check the sanitized env built by buildCodingProcessEnv)
  3. Verify with `which rg || which grep` inside the same container/PATH the agent uses, not your interactive shell
  4. As a last resort in stripped images, base the image on one that includes coreutils (e.g. debian-slim instead of distroless)

Example fix

# before: distroless image, no rg/grep
FROM gcr.io/distroless/nodejs22

# after: add ripgrep
FROM node:22-slim
RUN apt-get update && apt-get install -y --no-install-recommends ripgrep && rm -rf /var/lib/apt/lists/*
Defensive patterns

Strategy: validation

Validate before calling

import { spawnSync } from "node:child_process";

function hasSearchBackend(): boolean {
  for (const bin of ["rg", "grep"]) {
    const probe = spawnSync(bin, ["--version"], { stdio: "ignore" });
    if (probe.error === undefined) return true;
  }
  return false;
}

if (!hasSearchBackend()) throw new Error("install ripgrep or grep before enabling the grep tool");

Try / catch

try {
  const out = await grepTool.execute({ pattern: "TODO", scope: "src" }, signal);
} catch (err) {
  if (err instanceof Error && err.message.includes("neither rg nor grep")) {
    // environment capability problem: surface to operator, do not retry blindly
    throw new Error(`search unavailable in this environment: ${err.message}`);
  }
  throw err;
}

Prevention

When it happens

Trigger: Calling the `grep` tool in an environment where neither `rg` nor `grep` resolves on PATH: distroless/minimal Docker images, hardened sandboxes that strip /usr/bin, PATH sanitized by the process env builder, or Windows systems without ripgrep installed and no grep shim.

Common situations: Running the agent inside a slim container (node:slim, distroless) that omits coreutils; CI runners with restricted PATH; Windows dev machines where `rg` was never installed; sandbox profiles that deny executing search binaries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15). Data as JSON: /api/errors/09dc660b71472d0f. Report an issue: GitHub.