Conquering Neo4j Errors: GQLSTATUS Code to the Rescue
					Lead Software Engineer, Neo4j
6 min read

Have you ever encountered a Neo4j error message that was cryptic, inconsistent, or just plain outdated? For the longest time, improving error messages was a real Catch-22: Some users begged for clarity with rewordings and added information, while others needed the stability of existing messages because their tools and applications fragilely parsed them from the driver or query log.
This left users caught in a difficult trade-off, forcing them to choose between demanding clearer error explanations or retaining the system stability their existing applications relied upon. But what if there was a way to achieve both clarity and stability?
Even Batman Needs Clear Errors: An Example

Let’s imagine Batman planning to drive from Gotham City to Malmö, Sweden. He regularly needs to stop in other cities to charge the Batmobile, so he can’t travel on any road that takes more than five hours. To plan his route, Batman turns to Neo4j, but (surprisingly) he’s better at fighting crime than writing Cypher.
His first attempt is a bit off:
MATCH (a: Town {name:”Gotham”}), (b: Town {nam:”Malmö”}) 
MATCH p = allshortestPaths( (a)-[r* {travelTime: 5}]->(b)) 
RETURN pCode language: PHP (php)
Running this on an old Neo4j version yields a confusing, implementation-leaking error message that offers little help:

The Solution: Standardized Status — Stability for Your Tools, Clarity for Your Team
A major milestone in our multi-year project to enhance the Neo4j error experience was the introduction of the new GQL-compliant error system in Neo4j 5.26 LTS.
Now, whether your query results in a specific error, generates a notification, or achieves a successful outcome, you receive mandatory diagnostic information encapsulated in a GQL-status object. This object is designed to serve two distinct purposes: stability for tooling and clarity for human understanding.
It provides you with:
- GQLSTATUS code: This is the reliable interface for your tools. It is a five-digit alphanumeric code that acts as an immutable status code, which you can confidently programmatically depend on in your tools.
 - Status description: This is the clear message intended for human consumption. It provides a textual representation of the condition and can be improved over time without breaking your applications that rely on the stable GQLSTATUS code.
 - Diagnostic details: You also receive a diagnostic record with metadata and, if applicable, a more specific cause (which is itself another GQL-status object).
 
This structure resolves the long-standing tension between enhancing user experience (clearer messages) and protecting the stability of your applications (using fixed codes for programmatic analysis).
When Batman reruns his flawed query on the latest Neo4j version, he gets a clearer response:

Notice that the main GQL-status object has GQLSTATUS 42001, while the specific cause has GQLSTATUS 42N56. The two-letter class (42) and three-letter subclass (001 or N56) structure provides a hierarchical clarity, where, for example, it’s possible to depend on class 42 to cover all syntax and access rule violation errors.
The status description has the format error: <condition> — <subcondition>. <additional message> where the condition is a textual representation of the class and the subcondition is a textual representation of the subclass. The additional message contains more information, often including specific details directly related to the user query or database state.
The new error information will not only be shown but also returned by drivers and logged in the query log when JSON is used.
From Error to Working Query
Finding the new error much clearer, Batman checks the Cypher docs and refines his query to properly combine the shortest path with property predicates:
MATCH (a: Town {name:”Gotham”}), (b: Town {nam:”Malmö”}) 
MATCH p = ALL SHORTEST (a)(()-[r]->() WHERE r.travelTime <= 5)+(b) 
RETURN pCode language: PHP (php)
This query runs without error, but returns no results. Instead of giving up, Batman inspects the notifications in the query response:

The three warnings with GQLSTATUS class 01 show that Batman has made some mistakes with the labels and properties in his query (e.g., using Town instead of City). The single informational notification with GQLSTATUS 03N90 points out a potential performance issue, which Batman decides to ignore for now due to the limited size of his map.
Armed with the clear feedback, Batman makes his final, working correction to the query:
MATCH (a: City {name:”Gotham”}), (b: City {name:”Malmö”}) 
MATCH p = ALL SHORTEST (a)(()-[r]->() WHERE r.travelTime <= 5)+(b) 
RETURN pCode language: PHP (php)
Running this query, Batman finds that the best route from Gotham to Malmö goes through either Atlantis and Hogsmeade or Springfield and Rivendell.

Now that we’ve seen the new error system in action within Neo4j and helped Batman perfect his Cypher query, you might be asking: How does this translate to my application code?
Continue the Journey: Conquering Error in Code
If you want to follow Batman’s continued struggles as he expands his route planning to a Java application, be sure to tune in to the Conquering Neo4j Errors: GQLSTATUS Code to the Rescue talk on Nodes 2025!
There, I’ll deep-dive into the essential tools and resources for working with the new error system, including:
- Error handling with the Java driver: Practical code examples showing how to depend on the stable GQLSTATUS codes from programmatic error logic.
 - The Neo4j query log — now with a new 
errorInfoJSON object. - The error migrator tool in Neo4j Labs: A utility designed to help you smoothly transition existing applications to rely on the new GQLSTATUS codes.
 - The official documentation for the new error framework: Your comprehensive guide for all details of the new error system, including reference documentation for every GQLSTATUS code.
 
Summary
The era of cryptic errors and fragile parsing is over. Now it’s time for you to leverage the clarity of the status description and the stability of the immutable GQLSTATUS code across your entire stack, from query log to user interface.
Resources
- Neo4j Cypher Query Language
 - Declarative Route Planning With Cypher 25 — Graph Traversal Grows Up
 - How to Build a Knowledge Graph in 7 Steps
 
Conquering Neo4j Errors: GQLSTATUS Code to the Rescue was originally published in Neo4j Developer Blog on Medium, where people are continuing the conversation by highlighting and responding to this story.








