JuliusBrussee/caveman · error · Error

cave_eve_usage_missing

cave_eve_usage_missing

Error message

cave_eve_usage_missing

What it means

Returned by ValidateTenantSchema when the catalog query listing tenant tables and their RLS attributes (NOT NULL organization_id, relrowsecurity, relforcerowsecurity, policy existence/permissiveness/command) fails. The tables slice is a core input to the isolation checks, so a failure here aborts validation entirely. Causes are query-level: lost connection inside the read-only transaction, permission denied on pg_catalog columns, or a server whose catalog shape differs from what the query selects.

Source

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

  }, reasoningRequired, "cave_mastra_usage_missing");
}

function usageFromEveEvents(events: unknown[], reasoningRequired: boolean): NormalizedUsage {
  let totalInputTokens = 0;
  let outputTokens = 0;
  let cacheReadTokens = 0;
  let cacheWriteTokens = 0;
  let steps = 0;
  for (const event of events) {
    if (!isRecord(event) || event.type !== "step.completed" || !isRecord(event.data)) continue;
    const usage = record(event.data.usage, "cave_eve_usage_missing");
    totalInputTokens += strictInteger(usage.inputTokens, "cave_eve_usage_missing");
    outputTokens += strictInteger(usage.outputTokens, "cave_eve_usage_missing");
    cacheReadTokens += strictInteger(usage.cacheReadTokens, "cave_eve_usage_missing");
    cacheWriteTokens += strictInteger(usage.cacheWriteTokens, "cave_eve_usage_missing");
    steps++;
  }
  if (steps === 0 || reasoningRequired) throw new Error("cave_eve_usage_missing");
  if (cacheReadTokens + cacheWriteTokens > totalInputTokens) {
    throw new Error("cave_eve_usage_missing");
  }
  const inputTokens = totalInputTokens - cacheReadTokens - cacheWriteTokens;
  return normalizeUsage({
    inputTokens,
    outputTokens,
    cacheReadTokens,
    cacheWriteTokens,
    reasoningTokens: 0,
    totalTokens: inputTokens + outputTokens + cacheReadTokens + cacheWriteTokens,
  }, false, "cave_eve_usage_missing");
}

function normalizeUsage(
  value: Record<keyof NormalizedUsage, unknown>,
  reasoningRequired: boolean,
  error: string,

View on GitHub (pinned to 27d5a3981a)

Solutions

  1. Read the wrapped driver error: permission denied -> grant catalog read (pg_read_all_data or explicit grants on pg_catalog relations); connection reset -> fix network/keepalive and retry validation
  2. Confirm the target is vanilla Postgres the catalog queries were written for
  3. Re-run the inspection SQL by hand inside a READ ONLY REPEATABLE READ transaction as the same role to reproduce
  4. Retry ValidateTenantSchema with backoff at startup for transient failures

Example fix

-- reproduce as the validation role
BEGIN TRANSACTION READ ONLY ISOLATION LEVEL REPEATABLE READ;
SELECT c.relname, c.relrowsecurity, c.relforcerowsecurity
FROM pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public';
ROLLBACK;
Defensive patterns

Strategy: try-catch

Validate before calling

// Verify catalog readability as the validation role before startup validation:
func preflightCatalogRead(ctx context.Context, conn *pgx.Conn) error {
    rows, err := conn.Query(ctx, `
        SELECT c.relname, c.relrowsecurity, c.relforcerowsecurity
          FROM pg_catalog.pg_class c
          JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
         WHERE n.nspname = 'public' LIMIT 1`)
    if err != nil {
        return fmt.Errorf("catalog read denied; grant pg_read_all_data or pg_catalog grants: %w", err)
    }
    rows.Close()
    return nil
}

Type guard

func isInspectTablesErr(err error) bool {
    return err != nil && strings.HasPrefix(err.Error(), "postgres: inspect tenant tables")
}

func isPermissionDenied(err error) bool {
    return err != nil && strings.Contains(err.Error(), "permission denied")
}

Try / catch

err := postgresconfig.ValidateTenantSchema(ctx, pool)
if isInspectTablesErr(err) {
    switch {
    case isPermissionDenied(errors.Unwrap(err)):
        return fmt.Errorf("grant catalog read to the validation role: %w", err) // fix grants, do not retry
    case errors.Is(errors.Unwrap(err), context.DeadlineExceeded), isNetErr(errors.Unwrap(err)):
        err = retryValidation(ctx, pool, 3) // transient: retry
    }
}
if err != nil { return err }

Prevention

When it happens

Trigger: The inspector role lacking SELECT on pg_class/pg_namespace attributes joined with pg_policy; connection dropping inside the open transaction; running against a Postgres version or a wrapper (CockroachDB, Yugabyte) with different catalog columns.

Common situations: Hardening the validation role too far and losing catalog read access; network flaps during long startup sequences; pointing validation at a non-vanilla Postgres compatible server.

Related errors


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