Q:

NDSolve does not correctly evaluate If combined when using replacement rules

I have reduced my problem to the following example where NDSolve produces the error: 

"NDSolve::nlnum: The function value {x[t]} is not a list of numbers with dimensions {1} at {t, x[t], NDSolve`s$907226[t]} = {2., 5., 1}. >>"

tr = s[t] /. s[t] -> x[t]
ts = NDSolve[{x'[t] == If[x[t] < 20, 2, tr], x[0] == 3}, x[t], {t, 0, 10}]
Plot[Evaluate[x[t] /. ts], {t, 0, 10}, PlotRange -> All]

In contrast, removing the if condition leads to a working NDSolve, but certainly not to the initially expected solution:
tr = s[t] /. s[t] -> x[t]
ts = NDSolve[{x'[t] == tr, x[0] == 3}, x[t], {t, 0, 10}]
Plot[Evaluate[x[t] /. ts], {t, 0, 10}, PlotRange -> All]

Furthermore, not using replacement rules (Variable tr) works flawlessly and gives the expected result. Why is that so?
ts = NDSolve[{x'[t] == If[x[t] < 20, 2, x[t]], x[0] == 3}, x[t], {t, 0, 10}]
Plot[Evaluate[x[t] /. ts], {t, 0, 10}, PlotRange -> All]

My guess is that there is something off with the order of evaluation Mathematica uses, but I couldn't find any applicable examples or explanation. What is the culprit here?

A:

You are right, it is a matter of the order of evaluation. If has the attribute HoldRest, so you must evaluate tr explicitly in its argument list.
tr = s[t] /. s[t] -> x[t];
ts = NDSolve[{x'[t] == If[x[t] < 20, 2, Evaluate @ tr], x[0] == 3}, x[t], {t, 0, 10}];
Plot[Evaluate[x[t] /. ts], {t, 0, 10}, PlotRange -> All]

