JuliusBrussee/caveman · error · Error

caveman agent: unknown tool result policy ${JSON.stringify(r

Error message

caveman agent: unknown tool result policy ${JSON.stringify(result)}

What it means

The tool result policy controls how tool output is returned to the model: "auto", "inline", "page", "compress", or "exact_ccr". tool() accepts either a string policy or an object (an artifact policy normalized via artifactResultPolicy). After normalization, anything outside the five allowed strings throws 'unknown tool result policy'.

Source

Thrown at packages/agent/src/primitives.ts:138

export function tool<Input, Output, TResult>(
  options: StandardJSONToolOptions<Input, Output, TResult>,
): ToolDefinition<Output, TResult>;
export function tool(
  options: ToolOptions<TSchema, unknown> |
    StandardToolOptions<unknown, unknown, unknown> |
    StandardJSONToolOptions<unknown, unknown, unknown>,
): ToolDefinition<unknown, unknown> {
  if (!/^[a-zA-Z][a-zA-Z0-9_-]{0,127}$/.test(options.name)) {
    throw new Error(`caveman agent: invalid tool name ${JSON.stringify(options.name)}`);
  }
  if (!["read", "write", "idempotent", "external"].includes(options.effect)) {
    throw new Error(`caveman agent: unknown tool effect ${JSON.stringify(options.effect)}`);
  }
  const result = typeof options.result === "object"
    ? artifactResultPolicy(options.result)
    : options.result ?? "auto";
  if (!["auto", "inline", "page", "compress", "exact_ccr"].includes(result)) {
    throw new Error(`caveman agent: unknown tool result policy ${JSON.stringify(result)}`);
  }
  const timeoutMs = options.timeoutMs ?? 30_000;
  if (!Number.isSafeInteger(timeoutMs) || timeoutMs <= 0) {
    throw new Error("caveman agent: tool timeoutMs must be a positive integer");
  }
  const standard = standardToolSchema(options.input);
  let input: TSchema;
  if (standard === undefined) {
    input = options.input as TSchema;
  } else {
    let converted = "inputJSONSchema" in options
      ? options.inputJSONSchema
      : undefined;
    if (converted === undefined && standard.jsonSchema !== undefined) {
      try {
        converted = standard.jsonSchema.input({ target: "draft-07" });
      } catch (error) {
        throw new Error("caveman agent: Standard Schema cannot emit draft-07 input JSON Schema", {

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Use one of the five literals; omit result to get the default "auto"
  2. Choose deliberately: small outputs -> "inline"; large outputs -> "page"; context-sensitive shrinking -> "compress"; byte-exact capture -> "exact_ccr"
  3. After upgrading the package, grep your codebase for result: and re-check each value against the current allowed list

Example fix

// before
const t = tool({ name: "search", effect: "read", result: "summary", execute: ... });

// after
const t = tool({ name: "search", effect: "read", result: "compress", execute: ... });
Defensive patterns

Strategy: validation

Validate before calling

const POLICIES = ["auto", "inline", "page", "compress", "exact_ccr"];
if (cfg.result !== undefined && !POLICIES.includes(cfg.result)) {
  throw new Error(`result policy must be one of ${POLICIES.join(", ")}, got ${JSON.stringify(cfg.result)}`);
}

Type guard

type ResultPolicy = "auto" | "inline" | "page" | "compress" | "exact_ccr";
const isResultPolicy = (v: unknown): v is ResultPolicy =>
  typeof v === "string" && ["auto", "inline", "page", "compress", "exact_ccr"].includes(v);

Prevention

When it happens

Trigger: Passing result: "summary", "stream", "text", null, or a misspelled option like "compres". Also fires when artifactResultPolicy returns a non-allowed string for the object form.

Common situations: Assuming an arbitrary string is forwarded verbatim, upgrading from an older version that supported a since-removed policy name (e.g. a renamed paging mode), or copy-pasting docs from a different major version.

Related errors


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