JuliusBrussee/caveman · error
cavemanExporterConfig: protocol
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 pointed at the Caveman gateway, whose /otlp/v1/traces endpoint decodes protobuf-JSON only. The protocol option exists mainly to catch configs copied from standard OpenTelemetry setups: anything other than 'http/json' (the default) is rejected up front, instead of failing later with opaque 4xx responses from the gateway.
Solutions
- Omit the protocol option entirely — it defaults to 'http/json'
- Or set protocol: 'http/json' explicitly
- Keep transport concerns in options.headers (custom auth headers), not protocol
Example fix
// before
const cfg = cavemanExporterConfig({ baseUrl, apiKey, projectId, environment, protocol: 'http/protobuf' });
// after
const cfg = cavemanExporterConfig({ baseUrl, apiKey, projectId, environment }); // defaults to 'http/json' Defensive patterns
Strategy: type-guard
Type guard
type CavemanProtocol = 'http/json';
function isSupportedProtocol(value: unknown): value is CavemanProtocol {
return value === undefined || value === 'http/json';
} Prevention
- Omit the protocol option — 'http/json' is the only supported and default value
- When porting OpenTelemetry configs, strip protocol/transport fields before reuse
- Type exporter options narrowly so unsupported protocol literals fail at compile time
When it happens
Trigger: cavemanExporterConfig({ baseUrl, apiKey, projectId, environment, protocol: 'grpc' }) or protocol: 'http/protobuf' — the values standard OTLP Node SDKs and collector configs use.
Common situations: Porting an existing OpenTelemetry config where http/protobuf or grpc is the norm; a version upgrade that added protocol validation to previously-silent misconfiguration; copy-paste from generic OTLP exporter docs.
Related errors
- otlp decode
- : MCP ownership journal failed; native config may already…
- MCP transaction failed and rolled back
- MCP transaction failed and safe recovery was blocked: …
- MCP transaction state kept changing; refusing mutation
AI-assisted analysis of JuliusBrussee/caveman@766dce6b13 (2026-08-18).
Data as JSON: /api/errors/90e55afe4ca8fae0.
Report an issue: GitHub.
Appendix: 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 766dce6b13)