ToolJet/ToolJet · error · GrpcOperationError

Service descriptor not found for ${serviceName}

Error message

Service descriptor not found for ${serviceName}

What it means

Thrown in buildReflectionClient when reflectionClient.getDescriptorBySymbol(serviceName) resolves to a falsy descriptor. The service was listed and has methods, but the reflection server could not return the FileDescriptorProto for that symbol. This is a reflection-protocol-level inconsistency: the symbol is enumerable but its descriptor is unavailable.

Source

Thrown at plugins/packages/grpcv2/lib/operations.ts:74

    if (!serviceNames || serviceNames.length === 0) {
      throw new GrpcOperationError('No services found via reflection');
    }

    if (!serviceNames.includes(serviceName)) {
      throw new GrpcOperationError(`Service ${serviceName} not found. Available services: ${serviceNames.join(', ')}`);
    }

    const methods: ListMethodsType[] = await reflectionClient.listMethods(serviceName, callOptions);

    if (!methods || methods.length === 0) {
      throw new GrpcOperationError(`Service ${serviceName} has no methods`);
    }

    const descriptor = await reflectionClient.getDescriptorBySymbol(serviceName, callOptions);

    if (!descriptor) {
      throw new GrpcOperationError(`Service descriptor not found for ${serviceName}`);
    }

    const packageObject = descriptor.getPackageObject({
      keepCase: true,
      enums: String,
      longs: String,
      defaults: true,
      oneofs: true
    });

    const service = findServiceInPackage(packageObject, serviceName);
    if (!service) {
      throw new GrpcOperationError(`Service ${serviceName} not found in proto descriptor`);
    }

    if (typeof service !== 'function') {
      throw new GrpcOperationError(`Service ${serviceName} is not a valid constructor function`);
    }

View on GitHub (pinned to 20602a8e10)

Solutions

  1. Retry the call — descriptor indexing can lag service listing during server startup.
  2. Update/restart the reflection server to ensure descriptor-by-symbol works.
  3. Fall back to import_proto_file or import_protos_from_filesystem discovery if reflection descriptors are unreliable.
Defensive patterns

Strategy: retry

Try / catch

async function withDescriptorRetry(fn, attempts = 3) {
  for (let i = 0; i < attempts; i++) {
    try { return await fn(); }
    catch (e) {
      if (e instanceof GrpcOperationError && /descriptor not found/.test(e.message) && i < attempts - 1) continue;
      throw e;
    }
  }
}

Prevention

When it happens

Trigger: Reflection server partial implementation that lists services but fails descriptor-by-symbol lookups; a corrupted or incomplete reflection response; descriptor cache miss on the server side; race between service registration and descriptor indexing.

Common situations: Incompatible reflection server implementation; server under load dropping descriptor responses; grpc-js-reflection-client version mismatch with server protocol; transient server state during hot reload.

Related errors


AI-assisted analysis of ToolJet/ToolJet@20602a8e10 (2026-08-13). Data as JSON: /api/errors/99c9c96c4145efa6. Report an issue: GitHub.