Skip to content

gRPC lookupByRID() throws RecordNotFoundException for an existing persisted vertex #6404

Closed

Description

@TobiasJoseHermann

ArcadeDB version

  • Server: 26.9.1-SNAPSHOT
  • Java client: 26.9.1-SNAPSHOT
  • Commit: ca89f56fa5de779e8d8153433b862ae3839f313c
  • Java: OpenJDK 21.0.11
  • HTTP port: 2480
  • gRPC port: 50051

The server and grpc-client were built from the same commit. The server startup
confirmed:

ArcadeDB Server v26.9.1-SNAPSHOT
(build ca89f56fa5de779e8d8153433b862ae3839f313c/.../main)
gRPC server started on 0.0.0.0:50051

Description

RemoteGrpcDatabase.lookupByRID() throws RecordNotFoundException for an
existing, previously persisted vertex.

A SQL query executed through the same gRPC connection finds the vertex and
returns its RID. The HTTP client can also load the same RID correctly.

The failure is reproducible without an active transaction, so it is different
from #4260.

Reproducer

The following code uses an existing persisted vertex:

import com.arcadedb.database.RID;
import com.arcadedb.remote.grpc.RemoteGrpcDatabase;
import com.arcadedb.remote.grpc.RemoteGrpcServer;

import java.util.List;

RemoteGrpcServer server = new RemoteGrpcServer(
    "localhost", 50051, "root", password, true, List.of());

RemoteGrpcDatabase db = new RemoteGrpcDatabase(
    server,
    "localhost",
    50051,
    2480,
    databaseName,
    "root",
    password);

var rows = db.query(
    "sql",
    "select from Usuario where ldapId = ?",
    "heimdall");

RID rid = rows.next().getIdentity().orElseThrow();
System.out.println("GRPC_QUERY_RID=" + rid);

System.out.println(
    "REMOTE_SCHEMA_HAS_USUARIO=" + db.getSchema().existsType("Usuario"));

// Throws RecordNotFoundException even though the query above returned #13:0.
var record = db.lookupByRID(rid);

db.close();
server.close();

Output:

GRPC_QUERY_RID=#13:0
REMOTE_SCHEMA_HAS_USUARIO=false
com.arcadedb.exception.RecordNotFoundException: Record #13:0 not found
    at com.arcadedb.remote.grpc.RemoteGrpcDatabase.lookupByRID(RemoteGrpcDatabase.java:1298)
    at com.arcadedb.remote.grpc.RemoteGrpcDatabase.lookupByRID(RemoteGrpcDatabase.java:1259)

The equivalent HTTP lookup succeeds with the same server, database and RID:

import com.arcadedb.database.RID;
import com.arcadedb.remote.RemoteDatabase;

RemoteDatabase http = new RemoteDatabase(
    "localhost", 2480, databaseName, "root", password);

var record = http.lookupByRID(new RID("#13:0"));

System.out.println(record.getIdentity());
System.out.println(record.asVertex().getTypeName());
System.out.println(record.asVertex().getString("ldapId"));

http.close();

Output:

#13:0
Usuario
heimdall

Expected behavior

RemoteGrpcDatabase.lookupByRID(rid) should return a
RemoteImmutableVertex for the existing vertex, matching the HTTP client's
behavior.

Actual behavior

The gRPC query returns the correct RID, but lookupByRID(rid) throws a
misleading RecordNotFoundException.

Root cause analysis

The stack trace points to the null check after grpcRecordToDBRecord() in
RemoteGrpcDatabase.lookupByRID():

final Record record = grpcRecordToDBRecord(resp.getRecord());
if (record == null)
  throw new RecordNotFoundException("Record " + rid + " not found", rid);

It does not point to the preceding resp.getFound() check. This means the
server reported the RID as found, but the client failed to materialize the
returned GrpcRecord.

grpcRecordToDBRecord() requires a record category:

GrpcValue catFromGrpcRecord = grpcRecord.getPropertiesMap().get("@cat");

String cat;
if (catFromGrpcRecord != null)
  cat = catFromGrpcRecord.getStringValue();
else
  cat = mapRecordType(grpcRecord);

if (cat == null)
  return null;

For the returned vertex:

  1. ArcadeDbGrpcService.convertToGrpcRecord() sends the RID, type name and
    regular document properties, but does not add @cat.
  2. The fallback mapRecordType() relies on the remote schema.
  3. RemoteSchema.existsType("Usuario") returns false in this gRPC client,
    even after the server returned a row whose type is Usuario.
  4. The category remains null.
  5. grpcRecordToDBRecord() returns null.
  6. lookupByRID() translates that conversion failure into
    RecordNotFoundException.

SQL queries can appear to work because grpcRecordToResult() has a separate
fallback that creates a property-only ResultInternal when
grpcRecordToDBRecord() returns null. lookupByRID() has no equivalent
fallback because it must return a concrete Record.

Activity

  1. self-assigned this
    on Aug 18, 2026
  2. added theissue type on Aug 18, 2026
  3. added this to the 26.9.1 milestone on Aug 18, 2026
  4. added
    in progressThe team is actively working on this issue
    on Aug 18, 2026
  5. added 4 commits that reference this issue on Aug 18, 2026
  6. lvca commented on Aug 19, 2026

    @lvca
    Member

    Fixed and merged in #6435. ArcadeDbGrpcService now sends @cat on the wire for every element (matching JsonSerializer's HTTP behavior), so RemoteGrpcDatabase.lookupByRID() no longer depends on the fragile remote-schema fallback that caused the spurious RecordNotFoundException. One related, narrower edge case remains and is intentionally out of scope - see the follow-up notes on the PR/issue tracker.

  7. removed
    in progressThe team is actively working on this issue
    on Aug 19, 2026
  8. added
    grpcgRPC wire protocol (grpc/grpc-client/grpcw)
    on Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

buggrpcgRPC wire protocol (grpc/grpc-client/grpcw)

Type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions