JuliusBrussee/caveman · critical · Error
cave_vercel_usage_missing
cave_vercel_usage_missing
Error message
cave_vercel_usage_missing
What it means
Returned by validateRuntimeIdentity when the connected role is superuser, has the BYPASSRLS attribute, or directly owns a tenant table (a table in public with an organization_id column). Any of the three would let the runtime connection circumvent row-level security, so the pool refuses to start. This is the hard security gate of the runtime-pool design: privileged identities are structurally excluded, not merely discouraged.
Source
Thrown at packages/agent/src/adapters.ts:384
...input.usage,
costUsd: priced.catalogCostUsd,
usageBasis: "provider_reported",
priceBasis: "public_catalog",
evaluatedTransformIDs: [...input.request.evaluatedTransformIDs],
appliedTransformIDs: [...input.request.appliedTransformIDs],
recoveryResolved: input.request.recoveryResolved,
latencyMs: input.latencyMs,
};
}
function usageFromAISDK(value: unknown, reasoningRequired: boolean): NormalizedUsage {
const usage = record(value, "cave_vercel_usage_missing");
const input = record(usage.inputTokenDetails, "cave_vercel_usage_missing");
const output = record(usage.outputTokenDetails, "cave_vercel_usage_missing");
const totalInput = strictInteger(usage.inputTokens, "cave_vercel_usage_missing");
const cacheRead = optionalInteger(input.cacheReadTokens, "cave_vercel_usage_missing");
const cacheWrite = optionalInteger(input.cacheWriteTokens, "cave_vercel_usage_missing");
if (cacheRead + cacheWrite > totalInput) throw new Error("cave_vercel_usage_missing");
const noCache = input.noCacheTokens === undefined
? totalInput - cacheRead - cacheWrite
: strictInteger(input.noCacheTokens, "cave_vercel_usage_missing");
if (noCache + cacheRead + cacheWrite !== totalInput) {
throw new Error("cave_vercel_usage_missing");
}
const normalized = normalizeUsage({
inputTokens: noCache,
outputTokens: usage.outputTokens,
cacheReadTokens: cacheRead,
cacheWriteTokens: cacheWrite,
reasoningTokens: output.reasoningTokens,
totalTokens: usage.totalTokens,
}, reasoningRequired, "cave_vercel_usage_missing");
return normalized;
}
function usageFromMastra(value: unknown, reasoningRequired: boolean): NormalizedUsage {View on GitHub (pinned to 27d5a3981a)
Solutions
- Create a least-privileged LOGIN role (NOLOGIN off, NOSUPERUSER, NOBYPASSRLS) that owns no tenant tables, grant it only DML + EXECUTE, and use it in DATABASE_URL
- Run migrations as a separate privileged role so tenant tables are never owned by the runtime role
- Check the flags: SELECT rolSuper, rolBypassRLS FROM pg_roles WHERE rolname = current_user; and ownership: SELECT relname FROM pg_class WHERE pg_get_userbyid(relowner) = current_user;
- For managed Postgres, avoid the default admin account; provision a dedicated application login
Example fix
-- before: app connects as table owner CREATE ROLE app LOGIN PASSWORD '...' SUPERUSER; -- after CREATE ROLE app_migrator LOGIN PASSWORD '...'; -- owns schema/tables CREATE ROLE app_runtime LOGIN PASSWORD '...' NOSUPERUSER NOBYPASSRLS; GRANT USAGE ON SCHEMA public TO app_runtime; GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_runtime; -- app_runtime connects; app_migrator runs migrations
Defensive patterns
Strategy: validation
Validate before calling
// Assert the login is structurally unprivileged before pool construction:
func preflightLeastPrivilege(ctx context.Context, dbURL string) error {
conn, err := pgx.Connect(ctx, dbURL)
if err != nil { return err }
defer conn.Close(ctx)
var super, bypass bool
var owns int
err = conn.QueryRow(ctx, `
SELECT pg_is_in_recovery() OR false, -- placeholder replaced below
(SELECT rolsuper OR rolbypassrls FROM pg_roles WHERE rolname = current_user),
(SELECT count(*) FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'public' AND pg_get_userbyid(c.relowner) = current_user)`).Scan(new(bool), &super, &owns)
_ = bypass
if err != nil { return err }
if super || owns > 0 {
return fmt.Errorf("refusing privileged runtime role: super/bypass/owns=%d", owns)
}
return nil
} Type guard
func isUnsafeIdentityErr(err error) bool {
return err != nil && strings.HasPrefix(err.Error(), "postgres: unsafe runtime identity")
} Try / catch
pool, err := postgresconfig.NewPool(ctx, dbURL)
if err != nil {
if isUnsafeIdentityErr(err) {
// Never catch-and-continue: this is a security gate. Fix the role.
log.Fatal("runtime DB role is privileged (superuser/bypassrls/table owner); provision a least-privileged LOGIN role")
}
return err
} Prevention
- Create the app role with NOSUPERUSER NOBYPASSRLS and never let it own tenant tables
- Run migrations as a separate migrator role so ownership stays off the runtime login
- Include role-attribute assertions in deployment smoke tests: SELECT rolsuper, rolbypassrls FROM pg_roles WHERE rolname = '<app>'
- Avoid managed-Postgres default admin accounts for the application connection
When it happens
Trigger: DATABASE_URL pointing at the postgres superuser or the table owner; a role created with BYPASSRLS; migrating tables while logged in as the runtime role so it became the owner of new tenant tables; managed-database default users (e.g. cloudsqlsuperuser) that inherit superuser-like attributes.
Common situations: Copy-pasting the admin URL from a deploy guide into the app's secret; running migrations as the same role the app uses, transferring ownership of new tables to it; granting the runtime role ownership 'temporarily' and forgetting; RDS/Cloud SQL master accounts with bypassrls-like privileges.
Related errors
- cave_harness_incomplete_evidence
- cave_mastra_terminal_failure
- cave_eve_runtime_identity_missing
- cave_mastra_usage_missing
- cave_eve_usage_missing
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/42cfe918c4bcb32e.
Report an issue: GitHub.