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

  1. Remove the protocol option (it defaults to http/json) or set it to 'http/json' explicitly.
  2. If you need grpc/binary OTLP, export to a different collector endpoint and keep Caveman on http/json.
  3. 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

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


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