JuliusBrussee/caveman · error
cavemanExporterConfig: protocol ${protocol} is not accepted
Error message
cavemanExporterConfig: protocol ${protocol} is not accepted by ${baseUrl}/otlp/v1/traces; the Caveman OTLP endpoint decodes protobuf-JSON only. Use 'http/json'. What it means
cavemanExporterConfig builds an OTLP trace exporter for the Caveman gateway, which only accepts OTLP protobuf-JSON over HTTP at {baseUrl}/otlp/v1/traces. The protocol option exists for API symmetry, but any value other than the default 'http/json' (e.g. 'grpc' or 'http/protobuf') is rejected at config time with an explanatory message, because the gateway cannot decode binary protobuf bodies.
Source
Thrown at packages/mastra/src/index.ts:93
* Builds the OTLP settings a Mastra application passes to its telemetry config.
*
* The endpoint is Caveman's OTLP route (`POST {baseUrl}/otlp/v1/traces`). That
* handler decodes protobuf-JSON, not binary protobuf, so `http/json` is the only
* protocol it can accept — a protobuf or gRPC batch is rejected rather than
* silently dropped here.
*
* Auth: the gateway reads `x-cave-api-key` first and falls back to
* `authorization` (a `Bearer ` prefix is stripped before the key is parsed), so
* both headers are emitted and either one alone would authenticate.
*/
export function cavemanExporterConfig(options: CavemanExporterOptions): CavemanExporterConfig {
const baseUrl = requireBaseUrl(options.baseUrl, "cavemanExporterConfig: baseUrl");
const apiKey = requireNonEmpty(options.apiKey, "cavemanExporterConfig: apiKey");
const projectId = requireNonEmpty(options.projectId, "cavemanExporterConfig: projectId");
const environment = requireNonEmpty(options.environment, "cavemanExporterConfig: environment");
const protocol = options.protocol ?? "http/json";
if (protocol !== "http/json") {
throw new Error(
`cavemanExporterConfig: protocol ${protocol} is not accepted by ${baseUrl}/otlp/v1/traces; ` +
"the Caveman OTLP endpoint decodes protobuf-JSON only. Use 'http/json'.",
);
}
const endpoint = `${baseUrl}/otlp/v1/traces`;
const headers: Record<string, string> = {
"x-cave-api-key": apiKey,
authorization: `Bearer ${apiKey}`,
};
if (options.agentId) headers["x-cave-agent"] = options.agentId;
Object.assign(headers, options.headers ?? {});
// §23.3 of docs/self_learning_implementation_spec.md — the required metadata block.
const resourceAttributes: Record<string, string> = {
"caveman.project.id": projectId,
"caveman.environment": environment,
};View on GitHub (pinned to 27d5a3981a)
Solutions
- Remove the protocol option (it defaults to http/json) or set it to 'http/json' explicitly.
- If you need grpc/binary OTLP, export to a different collector endpoint and keep Caveman on http/json.
- Update the TypeScript type usage: CavemanExporterOptions['protocol'] only permits the JSON value.
Example fix
// before
cavemanExporterConfig({ baseUrl, apiKey, projectId, environment, protocol: "grpc" });
// after
cavemanExporterConfig({ baseUrl, apiKey, projectId, environment }); Defensive patterns
Strategy: type-guard
Validate before calling
const PROTOCOL = "http/json" as const;
// Only pass protocol when it equals the accepted value
const cfg = cavemanExporterConfig({ baseUrl, apiKey, projectId, environment, ...(protocol === PROTOCOL ? { protocol } : {}) }); Type guard
type AcceptedProtocol = "http/json";
function isAcceptedProtocol(v: string): v is AcceptedProtocol {
return v === "http/json";
} Prevention
- Treat http/json as the only protocol when targeting the Caveman OTLP endpoint.
- Do not copy OTel SDK protocol settings into cavemanExporterConfig.
- Let the default apply — omit protocol unless you need to be explicit.
When it happens
Trigger: Calling cavemanExporterConfig({ ..., protocol: 'grpc' }) or copying an OpenTelemetry SDK NodeSDK config where the protocol field was set for a standard OTLP exporter.
Common situations: Porting code from @opentelemetry/exporter-trace-otlp-grpc or -http, boilerplate that parameterizes protocol per environment, or assuming symmetry with the OTel spec's http/protobuf option.
Related errors
- option not found
- cave_harness_adapter_version_invalid
- cave_budget_denomination_ambiguous
- cave_budget_max_invalid
- cave_budget_output_floor_invalid
AI-assisted analysis of JuliusBrussee/caveman@27d5a3981a (2026-08-15).
Data as JSON: /api/errors/90e55afe4ca8fae0.
Report an issue: GitHub.