JuliusBrussee/caveman · error · Error

cave_eve_terminal_${result.status}

cave_eve_terminal_${result.status}

Error message

cave_eve_terminal_${result.status}

What it means

extractTools parses tool-catalog input for the MCP ({"tools":[…]}), OpenAI (array or {"functions":[…]}) shapes and first json.Unmarshals the whole document. Any JSON syntax error is wrapped as 'not valid JSON: %w', so the underlying err tells you the exact byte offset. This means the input never reached shape detection — it is malformed at the lexical/structural level.

Source

Thrown at packages/agent/src/adapters.ts:257

export function createEveAdapter(
  identity: HarnessAdapterIdentity,
  session: EveSessionBinding,
): HarnessAdapter {
  assertSupportedUpstream(identity, EVE_VERSION, "eve", "eve");
  return createHarnessAdapter("eve", identity, {
    package: "eve/client",
    class: "ClientSession",
    method: "send.result",
    usage: "step.completed.data.usage",
  }, async (request) => {
    const startedAt = performance.now();
    const response = await session.send({
      message: request.prompt,
      ...(request.signal === undefined ? {} : { signal: request.signal }),
    });
    const result = await response.result();
    if (result.status !== "completed") throw new Error(`cave_eve_terminal_${result.status}`);
    const identity = eveRuntimeIdentity(result.events);
    if (identity.upstreamVersion !== request.build.harness.upstream_version) {
      throw new Error("cave_harness_upstream_version_mismatch");
    }
    const usage = usageFromEveEvents(result.events, request.plan.reasoning !== "none");
    return harnessExecution({
      request,
      text: result.message ?? "",
      provider: identity.provider,
      model: identity.model,
      usage,
      latencyMs: Math.round(performance.now() - startedAt),
    });
  });
}

export interface MastraAgentBinding {
  generate(messages: string, options?: {

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Validate the input with jq or json.Unmarshal on []byte before piping: jq empty input.json.
  2. Strip non-JSON prefix/suffix output (progress lines, code fences, log noise) from the producer.
  3. If the producer emits NDJSON, aggregate the records into a single JSON array first: jq -s '.' input.ndjson.

Example fix

# before
curl -s https://host/v1/tools | caveman-shrink
# curl error page is not JSON

# after
resp=$(curl -sf https://host/v1/tools) && printf '%s' "$resp" | jq -c '{tools}' | caveman-shrink
Defensive patterns

Strategy: type-guard

Validate before calling

func isJSON(b []byte) bool {
    return json.Valid(b)
}

input, _ := io.ReadAll(os.Stdin)
if !isJSON(input) {
    log.Fatal("stdin is not valid JSON; run through: jq empty < input")
}

Type guard

func ensureJSONCatalog(b []byte) error {
    if !json.Valid(b) {
        return fmt.Errorf("not valid JSON: %s", findJSONIssue(b))
    }
    return nil
}

Try / catch

entries, err := extractTools(input)
if err != nil {
    if strings.HasPrefix(err.Error(), "not valid JSON") {
        // surface the offset from the wrapped error and re-check the producer pipeline
    }
}

Prevention

When it happens

Trigger: Piping text that is not JSON: an error message from an upstream command, truncated JSON (stream cut mid-write), a BOM or code fences around JSON, or concatenating multiple JSON documents into one stdin stream.

Common situations: curl failing and piping an HTML error page into the shrinker; a generator printing 'Progress: ...' lines before the JSON; copying JSON with smart quotes or trailing commas; feeding NDJSON (newline-delimited) where one document was expected.

Related errors


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