Troubleshooting Empty Result Sets and Missing Records in SurrealDB Graph Queries
Learn how to diagnose and fix 'Record Not Found' errors in SurrealDB, focusing on record ID formatting, FETCH clauses, and graph relation traversal.
21 Jul 2026, 00:44 UTC

The Problem: The 'Invisible' Record
In SurrealDB, it is common to encounter a scenario where a record exists in the database, but a query using a graph relation or a record ID returns an empty result set or a record link that refuses to expand. This typically happens when there is a mismatch between how the record is referenced and how it is stored, or when the query context lacks the necessary scope to resolve the link.
Diagnostic Matrix: Identifying the Failure Point
| Symptom | Likely Cause | Diagnostic Tool |
|---|---|---|
Query returns [] despite known ID |
ID Format Mismatch | Direct SELECT by ID |
| Record returns, but linked field is just an ID | Missing FETCH clause |
Compare query with/without FETCH |
Graph traversal (->) returns nothing |
Edge direction or Table mismatch | SELECT * FROM edge_table |
| Permission denied or record missing | Namespace/DB Context shift | INFO FOR db |
Step-by-Step Resolution Path
1. Verify Record Existence and ID Syntax
SurrealDB record IDs must follow the table:id format. A common error is treating a record ID as a string or omitting the table prefix during a lookup.
Check: Run a direct selection on the suspected record. Run this in the SurrealDB CLI or via your SDK with administrative permissions.
-- Replace 'user:john' with your actual table and ID
SELECT * FROM user:john;
Finding: If this returns [], the record does not exist in the current namespace/database, or the ID is misspelled. If it returns data, the issue lies in your relational query logic.
2. Validate Namespace and Database Context
If you are using a multi-tenant architecture, your session might be pointed at the wrong database, making records in other databases invisible.
Check: Verify your current session context.
INFO FOR db;
Finding: If the output does not match the database where the record was created, use USE NS namespace DB database; to switch contexts.
3. Distinguish Between Record Links and Strings
A field containing "user:john" (a string) is not the same as a field containing user:john (a record link). SurrealDB cannot traverse or fetch strings.
Check: Inspect the raw data of the record containing the link.
SELECT linked_field FROM table:record_id;
Finding: If the result is wrapped in quotes (e.g., "user:john"), it is a string. You must update the record to a proper record ID using the UPDATE statement without quotes around the ID value.
4. Resolve 'Unexpanded' Links with FETCH
By default, SurrealDB returns the record ID for linked fields to save bandwidth. To see the actual content of the linked record, you must explicitly request it.
Example Configuration:
Suppose you have a post record linked to a user record via a field called author.
Incorrect (Returns ID only):
SELECT author FROM post:123;
Correct (Returns User Object):
SELECT author FETCH author FROM post:123;
Risk: Avoid using FETCH ALL on records with deep nesting or hundreds of relations, as this can cause significant memory overhead on the server.
5. Debugging Graph Edge Traversal
When using the -> or <- operators, the query fails if the edge table name is omitted or the direction is reversed.
Check: Ensure the edge table exists and connects the two records.
-- Check if any edges exist between the two records
SELECT * FROM purchased WHERE in = user:john AND out = product:laptop;
Finding: If the edge exists but SELECT ->purchased->product FROM user:john returns nothing, verify that the edge direction (in/out) matches your traversal operator.
Rollback and Recovery
If you accidentally converted record links to strings during a bulk update, you can revert them using a type::record() cast (depending on version) or by re-importing the correct ID format:
UPDATE table SET linked_field = type::record(linked_field);
Escalation Criteria
If the following conditions are met and the record is still missing, escalate to database administration or SurrealDB support:
SELECT * FROM table:idreturns empty, but the record is visible in a backup or previous session.- The
INFO FOR dbconfirms the correct context, but the record is unreachable via any method. - The issue only occurs when querying through a specific SDK version, while the CLI returns the data correctly.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.