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
- Retry the call — descriptor indexing can lag service listing during server startup.
- Update/restart the reflection server to ensure descriptor-by-symbol works.
- 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
- Retry reflection descriptor lookups — they can lag during server startup.
- Ensure the reflection server fully indexes descriptors before serving.
- Fall back to file-based discovery if descriptor-by-symbol is persistently broken.
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
- No services found via reflection
- Service ${serviceName} not found. Available services: ${serv
- Service ${serviceName} has no methods
- Service ${serviceName} not found in proto descriptor
- Service ${serviceName} is not a valid constructor function
AI-assisted analysis of ToolJet/ToolJet@20602a8e10 (2026-08-13).
Data as JSON: /api/errors/99c9c96c4145efa6.
Report an issue: GitHub.