The problem with your command is that you are asking the command block running it to Tag itself if an arrow [Execute At arrow] has the closest player with a certain bow [@p[nbt...], in which fails since a command block can not even be tagged.
To fix this, you must change it to:
/execute as @e[type=minecraft:arrow] at @s run execute if entity @p[nbt={SelectedItem:{id:"minecraft:bow",tag:{display:{Name:"{\"text\":\"TP Bow\"}"}}}}] run tag @s add tparrow
This way, it will execute as and at the arrow, tagging it self
However, if you are going to use this in multiplayer, there is some bugs. First, if a player uses a normal bow, and another player or even the same one selects, later on, the bow with the correct name, it will be tagged and teleported. Secondly, if you shoot it near a friend, depending on how you programmed the rest, it might end up teleporting him.
Here it is a chain of commands to prevent these bugs but before, create this scoreboard
/scoreboard objectives add Bow minecraft.used:minecraft.bow
Here is the chain:
/execute as @a[scores={Bow=1},nbt={SelectedItem:{id:"minecraft:bow",tag:{display:{Name:"{\"text\":\"TP Bow\"}"}}}}] at @s run tag @e[type=minecraft:arrow,distance=0..2,sort=nearest,limit=1] add tparrow
/execute as @e[type=minecraft:arrow,tag=tparrow] at @s run tag @p[distance=0..2,scores={Bow=1}] add tpplayer
/execute as @e[type=minecraft:arrow,tag=tparrow,nbt={inGround:1b}] at @s run tp @p[tag=tpplayer] ~ ~ ~
/execute as @e[type=minecraft:arrow,tag=tparrow,nbt={inGround:1b}] at @s run tag @a[distance=0..1] remove tpplayer
/execute as @e[type=minecraft:arrow,tag=tparrow,nbt={inGround:1b}] at @s run kill @s
/scoreboard players set @a Bow 0
The first command block should be a "Repeat" one and the rest should be "Chain", All connected up.
If you wish to only tag the arrow while fixing those bugs: create the scoreboard and use the 1st, 2nd and last commands in the chain.