Q:

How do I debug why a node is evaluated? 

In Tensorflow, Placeholders must only be fed if the goal depends on it:
x = tf.placeholder(tf.int32, [], "x")
y = 2 * x1
y = tf. Print(y, ["Computed y"])
z = 2 * y

# Error: should feed "x"
z.eval()

# OK, because y is not actually computed
z.eval({y: 1})

Now, in my more complex graph, I have the problem that I get an error that some placeholders are not fed, but I think that they shouldn't be needed, by the same mechanism as illustrated above. 
How can I debug this?  The error message only states which placeholder is needed, but not why.  It would be helpful to get the path from the placeholder to the goal. 
How can I get this information? 

A:

If the graph is not huge, you could just do backward graph search from target node
ie, 
def find(start, target):
    """Returns path to parent from given start node"""
    if start == target:
        return [target]
    for parent in start.op.inputs:
        found_path = find(parent, target)
        if found_path:
            return [start]+found_path
    return []

To use it
tf.reset_default_graph()
a1 = tf.ones(())
b1 = tf.ones(())
a2 = 2*a1
b2 = 2*b1
a3 = 2*a2
b3 = 2*b2
d4 = b3+a3
find(d4, a1)

Should return
[<tf. Tensor 'add:0' shape=() dtype=float32>,
 <tf. Tensor 'mul_2:0' shape=() dtype=float32>,
 <tf. Tensor 'mul:0' shape=() dtype=float32>,
 <tf. Tensor 'ones:0' shape=() dtype=float32>]

If the graph is large, you can speed it up by restricting the search to ops between them
import tensorflow.contrib.graph_editor as ge
ops_between = ge.get_walks_intersection_ops(source, target)

ge.get_walks_intersection_ops doc

