Looking at usage patterns, we see that the recommended usage is:
program_hw_devices [lindex [get_hw_devices] 0]
Given the text of the output of get_hw_devices
is a “simple” word (no spaces or Tcl metacharacters), I suspect that the device tokens are actually special values that have non-trivial types hanging off the back end of their representation. We don't recommend that approach as it can lead to very weird error messages (such as the one you got), but given that it is so, you need to use exactly the pattern as described above so that you strip exactly one level of list-ness away.
For future reference, the script at that link (which was supposedly working) was:
# Connect to the Digilent Cable on localhost:3121
connect_hw_server -url localhost:3121
current_hw_target [get_hw_targets */xilinx_tcf/Digilent/12345]
open_hw_target
# Program and Refresh the XC7K325T Device
current_hw_device [lindex [get_hw_devices] 0]
refresh_hw_device -update_hw_probes false [lindex [get_hw_devices] 0]
set_property PROGRAM.FILE {C:/design.bit} [lindex [get_hw_devices] 0]
set_property PROBES.FILE {C:/design.ltx} [lindex [get_hw_devices] 0]
program_hw_devices [lindex [get_hw_devices] 0]
refresh_hw_device [lindex [get_hw_devices] 0]
I would have written it more like this myself:
# Connect to the Digilent Cable on localhost:3121
connect_hw_server -url localhost:3121
current_hw_target [get_hw_targets */xilinx_tcf/Digilent/12345]
open_hw_target
# Program and Refresh the XC7K325T Device
set Device [lindex [get_hw_devices] 0]
current_hw_device $Device
refresh_hw_device -update_hw_probes false $Device
set_property PROGRAM.FILE "C:/design.bit" $Device
set_property PROBES.FILE "C:/design.ltx" $Device
program_hw_devices $Device
refresh_hw_device $Device
so that I only do the list extraction once, but that's purely style; if one works, the other should as well.