apoc.path.combine(path,path1) as paths throws Can't coerce `NO_VALUE` to Path error in linux
Issue by shahadp
Tuesday Feb 25, 2020 at 19:57 GMT
Originally opened as https://github.com/neo4j-contrib/neo4j-apoc-procedures/issues/1427
Guidelines
Please note that GitHub issues are only meant for bug reports/feature requests. If you have questions on how to use APOC, please ask on the Neo4j Discussion Forum instead of creating an issue here.
Expected Behavior (Mandatory)
apoc.convert.toTree(paths) return valid json response.
Actual Behavior (Mandatory)
Returns error. Neo.ClientError.Statement.TypeError . Can't coerce NO_VALUE to Path
How to Reproduce the Problem
The below issue happens in linux redhat linux neo4j V4.0.0 enterprise & windows V4.0.0 enterprise
Create a category name it root. create sub_category relation subcategory node under that category (this can run into different depth). create products under subcategory. This happens only if you have sub_Category that dont have any product under that and some sub_category have some products
match path= (c:Category)-[:SUB_CATEGORY*]->(sc:SubCategory)
optional match path1= (sc)-[:PRODUCT*]->(p:product)
WITH apoc.path.combine(path,path1) as path0 with collect (path0) as paths call apoc.convert.toTree(paths) yield value return value
Simple Dataset (where it's possibile)
//Insert here a set of Cypher statements that helps us to reproduce the problem
match path= (c:Category)-[:SUB_CATEGORY*]->(sc:SubCategory)
optional match path1= (sc)-[:PRODUCT*]->(p:product)
WITH apoc.path.combine(path,path1) as path0 with collect (path0) as paths call apoc.convert.toTree(paths) yield value return value
### Steps (Mandatory)
1. Run the above cypher couple of times using browser, the error should appear with in 5-10 execution or repeat until it reproduces.
1.
1.
## Screenshots (where it's possibile)
The below query executes 5 times fine and six time returns an error Neo.ClientError.Statement.TypeError .
Can't coerce `NO_VALUE` to Path
Until next restart it wont work.
match path= (c:Category)-[:SUB_CATEGORY*]->(sc:SubCategory)
optional match path1= (sc)-[:PRODUCT*]->(p: product)
WITH apoc.path.combine(path,path1) as path0 with collect (path0) as paths call apoc.convert.toTree(paths) yield value return value
return paths works well, it seems apoc.convert.toTree() yield value may be having some issue not sure . after 5 execution it just returns this error can't coerce ..
## Specifications (Mandatory)
it seems apoc.convert.toTree() yield value may be having some issue not sure . after 5 execution it just returns this error can't coerce
Currently used versions
### Versions
- OS: Red Hat Enterprise Linux 8 (HVM), windows 2016 server
- Neo4j: neo4j V4.0.0 enterprise
- Neo4j-Apoc: 4.0.0.4
### Error details from query.log
org.neo4j.exceptions.CypherTypeException: Can't coerce `NO_VALUE` to Path
at org.neo4j.cypher.operations.CypherCoercions.cantCoerce(CypherCoercions.java:287)
at org.neo4j.cypher.operations.CypherCoercions.asPathValue(CypherCoercions.java:136)
at org.neo4j.codegen.Expression46/0x0000000101de1c40.project(Unknown Source)
at org.neo4j.cypher.internal.runtime.slotted.expressions.CompileWrappingProjection.project(CompiledExpressionConverter.scala:160)
at org.neo4j.cypher.internal.runtime.pipelined.operators.ProjectOperator.operate(ProjectOperator.scala:41)
at org.neo4j.cypher.internal.runtime.pipelined.operators.OperatorTask.operateWithProfile(Operator.scala:251)
at org.neo4j.cypher.internal.runtime.pipelined.operators.OperatorTask.operateWithProfile$(Operator.scala:241)
at org.neo4j.cypher.internal.runtime.pipelined.operators.ProjectOperator.operateWithProfile(ProjectOperator.scala:23)
at org.neo4j.cypher.internal.runtime.pipelined.PipelineTask.executeOperators(PipelineTask.scala:65)
at org.neo4j.cypher.internal.runtime.pipelined.PipelineTask.executeWorkUnit(PipelineTask.scala:48)
at org.neo4j.cypher.internal.runtime.pipelined.Worker.executeTask(Worker.scala:128)
at org.neo4j.cypher.internal.runtime.pipelined.Worker.workOnQuery(Worker.scala:84)
at org.neo4j.cypher.internal.runtime.pipelined.execution.CallingThreadExecutingQuery.request(CallingThreadExecutingQuery.scala:30)
at org.neo4j.cypher.internal.PipelinedRuntime$PipelinedRuntimeResult.request(PipelinedRuntime.scala:326)
at org.neo4j.cypher.internal.result.StandardInternalExecutionResult.request(StandardInternalExecutionResult.scala:88)
at org.neo4j.cypher.internal.result.ClosingExecutionResult.request(ClosingExecutionResult.scala:135)
at org.neo4j.bolt.runtime.AbstractCypherAdapterStream.handleRecords(AbstractCypherAdapterStream.java:105)
at org.neo4j.bolt.v3.messaging.ResultHandler.onPullRecords(ResultHandler.java:41)
at org.neo4j.bolt.v4.messaging.PullResultConsumer.consume(PullResultConsumer.java:42)
at org.neo4j.bolt.runtime.statemachine.impl.TransactionStateMachine$State.consumeResult(TransactionStateMachine.java:511)
at org.neo4j.bolt.runtime.statemachine.impl.TransactionStateMachine$State$2.streamResult(TransactionStateMachine.java:355)
at org.neo4j.bolt.runtime.statemachine.impl.TransactionStateMachine.streamResult(TransactionStateMachine.java:92)
at org.neo4j.bolt.v4.runtime.InTransactionState.processStreamResultMessage(InTransactionState.java:73)
at org.neo4j.bolt.v4.runtime.AbstractStreamingState.processUnsafe(AbstractStreamingState.java:49)
at org.neo4j.bolt.v4.runtime.InTransactionState.processUnsafe(InTransactionState.java:60)
at org.neo4j.bolt.v3.runtime.FailSafeBoltStateMachineState.process(FailSafeBoltStateMachineState.java:48)
at org.neo4j.bolt.runtime.statemachine.impl.AbstractBoltStateMachine.nextState(AbstractBoltStateMachine.java:143)
at org.neo4j.bolt.runtime.statemachine.impl.AbstractBoltStateMachine.process(AbstractBoltStateMachine.java:91)
at org.neo4j.bolt.messaging.BoltRequestMessageReader.lambda$doRead$1(BoltRequestMessageReader.java:90)
at org.neo4j.bolt.runtime.DefaultBoltConnection.lambda$enqueue$0(DefaultBoltConnection.java:151)
at org.neo4j.bolt.runtime.DefaultBoltConnection.processNextBatchInternal(DefaultBoltConnection.java:240)
at org.neo4j.bolt.runtime.DefaultBoltConnection.processNextBatch(DefaultBoltConnection.java:175)
at org.neo4j.bolt.runtime.DefaultBoltConnection.processNextBatch(DefaultBoltConnection.java:165)
at org.neo4j.bolt.runtime.scheduling.ExecutorBoltScheduler.executeBatch(ExecutorBoltScheduler.java:212)
at org.neo4j.bolt.runtime.scheduling.ExecutorBoltScheduler.lambda$scheduleBatchOrHandleError$2(ExecutorBoltScheduler.java:195)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)
Comment by jexp
Wednesday Feb 26, 2020 at 10:15 GMT
does this also happen if you pass an empty list or a null value to toTree
Comment by shahadp
Wednesday Feb 26, 2020 at 10:57 GMT
Passing empty list provides this response {
}
Passing null provides this resopnse
Failed to invoke procedure apoc.convert.toTree: Caused by: java.lang.NullPointerException
Please note this was working fine in v3.5.14 with apoc version apoc-3.5.0.5-all. Also after restart first 5 invocations work fine and 6th one onwards fails until restart or by modifying some values in cypher (like adding a relationship name makes it work again for 5 times and fails at 6th time- sometimes 4 and fails at 5th. Its a definte pattern).
Also happens only if use optional keyword ( means i have to pull the subcategory with no products under it as its not filled with product yet)
Comment by shahadp
Thursday Feb 27, 2020 at 00:50 GMT
After doing some more research on this subject it seems its not cause by apoc.covert.toTree, it is apoc.path.combine issue after 5 or 6 successful execution.
Th below query does not work--->
match path= (c:Category)-[:SUB_CATEGORY*]->(sc:SubCategory)optional match path1= (sc)-[:PRODUCT*]->(p:Product) WITH apoc.path.combine(path,path1) as path0 return path0 -->This does not work after 5 or 6 executions--> Exception::org.neo4j.driver.exceptions.ClientException: Can't coerce NO_VALUE to Path
The below query works---> so path, path1 are retrieved successfully. match path= (c:Category)-[r:SUB_CATEGORY*]->(sc:SubCategory) optional match path1= (sc)-[r1:PRODUCT*]->(p:Product) return path,path1
Comment by jexp
Friday Feb 28, 2020 at 15:06 GMT
Can you check the values returned on repeated execution of the working query that returns path1 and path2? If any of those is null?
Comment by shahadp
Monday Mar 02, 2020 at 21:41 GMT
path1 dont have any null value, but path2 because its optional match it will have some null values against the subcategory that dont have a product defined. Another environment details is i upgraded the datastore from 3.5.14 to 4.0 using database upgrade option. to verify the issue i also took a dumb and uploaded in a new datastore but still have the issue. Right now i found a work around to work on the issue by using apoc.path.expand. if i derive my path2 using apoc.path.expand by giving the start node it seems apoc.path.combine is not having any issue.
match path1= (c:Category)-[:SUB_CATEGORY*]->(sc:SubCategory) call apoc.path.expand(sc,'PRODUCT','Product',0,1) YIELD path as path2 WITH apoc.path.combine(path1,path2) as paths return paths
Comment by shahadp
Monday Mar 09, 2020 at 18:25 GMT
The issue is getting replicated in lots of places (for 4.0) and queries which previously worked with V3.5. I can see the pattern now its related to null. If there any operation related to null (optional match returns ) for e.g you have couple of values that require multiplication on a certain value.. so let us say we have 5 nodes, 3 having values (size as attribute name) and 2 having null values. size * 1.05 for all 5 nodes, it returns for 5 execution correct response and 6th one as below error. . I can see this pattern related to null and any complex dataset having null combination having this issue.
Comment by cchukuigwe
Thursday Mar 19, 2020 at 14:57 GMT
I can confirm that this is still happening in v4.0 on OPTIONAL MATCH returning null results. Exactly as described. Executes first few times then gives similar error as above:
neo4j.exceptions.ClientError: Failed to invoke procedure apoc.cypher.run: Caused by: org.neo4j.exceptions.CypherTypeException: Can't coerce NO_VALUE to Map
Comment by InverseFalcon
Tuesday Jul 28, 2020 at 20:08 GMT
As a workaround, we can use CASE as a safeguard to avoid the call if the optional value is null:
match path= (c:Category)-[:SUB_CATEGORY*]->(sc:SubCategory)
optional match path1= (sc)-[:PRODUCT*]->(p:Product)
WITH CASE WHEN path1 IS NOT NULL THEN apoc.path.combine(path,path1) ELSE path END as path0
return path0
Comment by shahadp
Tuesday Jul 28, 2020 at 22:34 GMT
Hi @InverseFalcon,
Thanks for the update really appreciated, that is exactly what i am doing to avoid the issue at the moment. With the new version (4.x) there are strange issues with cyphers that were previously working with 3.X version with zero issues.
Comment by tanvp112
Friday Aug 21, 2020 at 10:50 GMT
As a workaround, we can use CASE as a safeguard to avoid the call if the optional value is null:
match path= (c:Category)-[:SUB_CATEGORY*]->(sc:SubCategory) optional match path1= (sc)-[:PRODUCT*]->(p:Product) WITH CASE WHEN path1 IS NOT NULL THEN apoc.path.combine(path,path1) ELSE path END as path0 return path0
Hi InverseFalcon,
When tried with the suggestion with the apoc.path.combine example (https://neo4j.com/labs/apoc/4.1/graph-querying/path-querying/#path-functions-examples), the return result is not the same as the documentation stated.
MATCH (club:Club) OPTIONAL MATCH path1 = (club)-[:IN_LEAGUE]->(league) OPTIONAL MATCH path2 = (league)-[:IN_COUNTRY]->(country) WITH club, path1, path2 WHERE path1 IS NOT NULL and path2 IS NOT NULL // check for invalid path RETURN club.name, apoc.path.combine(path1, path2) AS path ORDER BY length(path)
Not sure if this is regression issue or the documented result is incorrect.
Thanks.
I am unable to reproduce the original bug in this issue, so will close due to that. If someone has a similar issue, with a reproducible data set, feel free to reopen.
As for the above question about the docs, you need to use OR not AND in the null check :)