NonUniqueTokenException. Can't launch database. Can't use cypher-shell to fix it

Hello friends,

I stumbled upon yet another roadblock. I'm running Neo4j 4.0.0 CE.
I was running the following query using the official python Neo4j Bolt driver:

session.run(
  "MATCH (u:User), (p:Podcast) WHERE p.podcastId = $podcastId AND u.uuid = $sub "
  "MERGE (u)-[eo:EDITOR_OF]->(p) "
  "ON CREATE SET eo.isActive = false, eo.lastVerificationRequestOnDT = datetime() "
  "ON MATCH SET eo.lastVerificationRequestOnDT = datetime() "
  "RETURN eo;",
  {'podcastId':podcast_id, 'sub': sub}
).single()

I was constantly getting the following error:

[ERROR] DatabaseError: Newly created token should be unique.

I've stoped the database and tried to restart but couldn't because of the following error I could identify by running neo4j-admin consistency-check:

org.neo4j.token.api.NonUniqueTokenException: The PropertyKey NamedToken[name:lastVerificationRequestedOnDT, id:91, internal:false] is not unique, it existed as null.

Now I'm not even able fix it through cypher-shell because of the following:

Unable to get a routing table for database 'graph.db' because this database is unavailable

And so I'm stuck!
Can anyone suggest the way to restore it without running a full backup?


Also, can anyone tell me why it was considered necessary for this relationship's property to be unique? There's no such constraint specified in my schema and there's nothing in the query that might indicate any need for uniqueness.


Thank you in advance.

OK, here's what I've found out:

The query above works like a charm in Neo4j 3.5.14 but not always in Neo4j 4.0.0. When I run it the first time after a full backup I get the aforementioned error:

[ERROR] DatabaseError: Newly created token should be unique.

be it in Neo4j browser or anything else. Then I'd tweak the query a bit just to change the format a bit, for example:

MATCH (u:User {uuid: "randomuuidhere"})
MATCH (p:Podcast {podcastId: "randompodcastidhere")
MERGE (u)-[eo:EDITOR_OF]->(p)
SET eo.isActive = false, eo.lastVerificationRequestOnDT = datetime()
RETURN eo

or

MATCH (u:User {uuid: "randomuuidhere"})
MATCH (p:Podcast {podcastId: "randompodcastidhere")
WITH u, p, datetime() AS dt
MERGE (u)-[eo:EDITOR_OF]->(p)
SET eo.isActive = false, eo.lastVerificationRequestOnDT = dt
RETURN eo

It would complain a couple of times but then start working.
If I then run the initial query, it'll work.

However, I can't leave it at this as, in the meantime, I've introduced a severe inconsistency in my DB that will prevent it from starting up next time and the check-consistency command will yield the result I described at the beginning of this thread.

So, somehow, a new property key of null is being created on a relationship when used in conjunction with datetime() in Neo4j 4.0.0 CE. This is not the case in Neo4j 3.5.14.

Is there any way for me to remove the null property key once it has been created and go on with my life?

Can you provide a means to replicate this, either with a query to create a small data set, or with a zipped graph?

Also any additional details about your case would be helpful, such as if you're seeing this after a migration from 3.5.14 (and if you've run a consistency check before upgrading, if this is the case), or if you can replicate this with a fresh 4.0.0 graph.

Also if this was a migration, can you confirm if this is from 3.5.14 community or enterprise edition, and if you can let us know the exact version of 4.0.0 you're using, and where and when you downloaded it, to make sure you're referring to the current release candidate or to MR3 or some earlier release.