"argument must be string" error when trying to print with GPX

So I discovered the new (to me) printer has a broken SD card reader (as in they actually managed to break the component off the board and I haven't taken it apart to do the rework yet), so I decided to attempt a print via USB. This is a QIDI Tech 1, just like my other printer (which is currently down with a fried mainboard and possibly a fried display and SD card reader as well, thanks to a manufacturer wiring issue - black for +24V and red for 0V from the factory - that led to me hooking up the replacement mainboard with reverse voltage). I'm running the OctoPi 0.15.0 image, which is OctoPrint 1.3.8, I believe.

I can upload the file to OctoPrint and load the file on the printer, but when I attempt to print, I get an error message and OctoPrint disconnects from the printer. Since this is an argument error writing to serial (see log below), the only real step I could think of was to make sure GPX was using the right flavor of gcode (problem exists with either setting), and to post a cry for help.

octoprint.log:

2018-05-15 14:59:57,256 - octoprint.plugins.GPX - INFO - Connecting through x3g.
2018-05-15 14:59:57,259 - octoprint.plugins.GPX - INFO - GPXPrinter created, port: 
/dev/ttyACM0, baudrate: 115200
2018-05-15 15:00:01,285 - octoprint.plugins.GPX - INFO - gpx.connect succeeded
2018-05-15 15:00:01,287 - octoprint.util.comm - INFO - Changing monitoring state fr
om "Offline" to "Opening serial port"
2018-05-15 15:00:01,299 - octoprint.util.comm - INFO - Changing monitoring state fr
om "Opening serial port" to "Detecting baudrate"
2018-05-15 15:00:01,315 - octoprint.util.comm - INFO - Changing monitoring state fr
om "Detecting baudrate" to "Operational"
2018-05-15 15:00:01,331 - octoprint.util.comm - INFO - M110 detected, setting curre
nt line number to 0
2018-05-15 15:00:03,396 - octoprint.util.comm - INFO - Printer reports firmware nam
e "Sailfish"
2018-05-15 15:00:11,382 - octoprint.util.comm - INFO - Changing monitoring state fr
om "Operational" to "Printing"
2018-05-15 15:00:11,408 - octoprint.util.comm - INFO - M110 detected, setting curre
nt line number to 0
2018-05-15 15:00:11,454 - octoprint.util.comm - ERROR - Unexpected error while writ
ing to serial port
Traceback (most recent call last):
  File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/util/comm.py", 
line 3005, in _do_send_without_checksum
    result = self._serial.write(to_send)
  File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint_GPX/gpxprinter.
py", line 131, in write
    self._append(gpx.write("%s" % data))
TypeError: argument 1 must be string without null bytes, not str
2018-05-15 15:00:11,472 - octoprint.util.comm - INFO - Changing monitoring state fr
om "Printing" to "Offline (Error: TypeError: 'argument 1 must be string without nul
l bytes, not str' @ comm.py:_do_send_without_checksum:3005)"
2018-05-15 15:00:11,701 - octoprint.plugins.printhistory - INFO - Can't parse addit
ional parameters from /home/pi/.octoprint/uploads/xyzCalibration_cube.x3g

serial.log (turned on and 5th attempt made):

2018-05-15 15:13:41,931 - Changing monitoring state from "Offline" to "Opening serial port"
2018-05-15 15:13:41,938 - Connected to: <GPX.gpxprinter.GpxPrinter instance at 0x6d7eb940>, starting monitor
2018-05-15 15:13:41,948 - Starting baud rate detection
2018-05-15 15:13:41,950 - Changing monitoring state from "Opening serial port" to "Detecting baudrate"
2018-05-15 15:13:41,958 - Recv: start
2018-05-15 15:13:41,965 - Changing monitoring state from "Detecting baudrate" to "Operational"
2018-05-15 15:13:41,979 - Recv:  Sailfish v7.8
2018-05-15 15:13:41,981 - Send: N0 M110 N0*125
2018-05-15 15:13:41,983 - Recv: echo: gcode to x3g translation by GPX
2018-05-15 15:13:42,018 - Recv: SD init fail
2018-05-15 15:13:42,021 - Recv:  T:26 /0 B:14 /0 T0:26 /0 T1:26 /0 @:0 B@:0
2018-05-15 15:13:44,030 - Recv: ok
2018-05-15 15:13:44,038 - Send: N1 M115*39
2018-05-15 15:13:44,043 - Recv: ok PROTOCOL_VERSION:0.1 FIRMWARE_NAME:Sailfish FIRMWARE_VERSION:7.8 FIRMWARE_URL:http://www.sailfishfirmware.com MACHINE_TYPE:r1d EXTRUDER_COUNT:2
2018-05-15 15:13:44,050 - Send: M21
2018-05-15 15:13:44,055 - Recv: ok
2018-05-15 15:13:44,057 - Recv: SD init fail
2018-05-15 15:13:46,966 - Send: M105
2018-05-15 15:13:47,003 - Recv: ok T:27 /0 B:14 /0 T0:27 /0 T1:26 /0 @:0 B@:0
2018-05-15 15:13:51,968 - Send: M105
2018-05-15 15:13:52,005 - Recv: ok T:26 /0 B:14 /0 T0:26 /0 T1:26 /0 @:0 B@:0
2018-05-15 15:13:56,968 - Send: M105
2018-05-15 15:13:57,002 - Recv: ok T:26 /0 B:14 /0 T0:26 /0 T1:26 /0 @:0 B@:0
2018-05-15 15:14:02,003 - Send: M105
2018-05-15 15:14:02,040 - Recv: ok T:26 /0 B:14 /0 T0:26 /0 T1:27 /0 @:0 B@:0
2018-05-15 15:14:04,328 - Changing monitoring state from "Operational" to "Printing"
2018-05-15 15:14:04,360 - Send: N0 M110 N0*125
2018-05-15 15:14:04,362 - Recv: ok
2018-05-15 15:14:04,364 - Send: (@build "xyzCalibration_cube")
2018-05-15 15:14:04,366 - Recv: ok
2018-05-15 15:14:04,368 - Send: N1 M136 (xyzCalibration_cube)*120
2018-05-15 15:14:04,385 - Recv: ok
2018-05-15 15:14:04,387 - Send: ?xyzCalibration_cube???i???0????x
2018-05-15 15:14:04,389 - Unexpected error while writing to serial port: TypeError: 'argument 1 must be string without null bytes, not str' @ comm.py:_do_send_without_checksum:3005
2018-05-15 15:14:04,397 - Changing monitoring state from "Printing" to "Offline (Error: TypeError: 'argument 1 must be string without null bytes, not str' @ comm.py:_do_send_without_checksum:3005)"
2018-05-15 15:14:06,391 - Connection closed, closing down monitor

OctoPrint Terminal:

Changing monitoring state from "Offline" to "Opening serial port"
Connected to: <GPX.gpxprinter.GpxPrinter instance at 0x6d7eb940>, starting monitor
Starting baud rate detection
Changing monitoring state from "Opening serial port" to "Detecting baudrate"
Recv: start
Changing monitoring state from "Detecting baudrate" to "Operational"
Recv:  Sailfish v7.8
Send: N0 M110 N0*125
Recv: echo: gcode to x3g translation by GPX
Recv: SD init fail
Recv:  T:26 /0 B:14 /0 T0:26 /0 T1:26 /0 @:0 B@:0
Recv: ok
Send: N1 M115*39
Recv: ok PROTOCOL_VERSION:0.1 FIRMWARE_NAME:Sailfish FIRMWARE_VERSION:7.8 FIRMWARE_URL:http://www.sailfishfirmware.com MACHINE_TYPE:r1d EXTRUDER_COUNT:2
Send: M21
Recv: ok
Recv: SD init fail
Send: M105
Recv: ok T:27 /0 B:14 /0 T0:27 /0 T1:26 /0 @:0 B@:0
Send: M105
Recv: ok T:26 /0 B:14 /0 T0:26 /0 T1:26 /0 @:0 B@:0
Send: M105
Recv: ok T:26 /0 B:14 /0 T0:26 /0 T1:26 /0 @:0 B@:0
Send: M105
Recv: ok T:26 /0 B:14 /0 T0:26 /0 T1:27 /0 @:0 B@:0
Changing monitoring state from "Operational" to "Printing"
Send: N0 M110 N0*125
Recv: ok
Send: (@build "xyzCalibration_cube")
Recv: ok
Send: N1 M136 (xyzCalibration_cube)*120
Recv: ok
Send: ?\x00\x00\x00\x00xyzCalibration_cube\x00?\x00\x00?\x00?\x03i\x01\x00\x00\x14\x00?\x04?\x00\x00\x00\x14\x00?\x00\x00\x00\x00\x00\x00\x00\x000???\x00\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00x
Unexpected error while writing to serial port: TypeError: 'argument 1 must be string without null bytes, not str' @ comm.py:_do_send_without_checksum:3005
Changing monitoring state from "Printing" to "Offline (Error: TypeError: 'argument 1 must be string without null bytes, not str' @ comm.py:_do_send_without_checksum:3005)"
Connection closed, closing down monitor

As a followup, I did find one pertinent thread via a google search, but python is one of the few mainstream languages I don't code in, so this may be a lot faster and easier for someone else to fix. Basically, it seems to be either an escaping issue or a situation where GPX is trying to send binary data in an incorrect manner. The link seems to indicate the former.

Turns out I forgot one little thing from the GPX plugin's instructions: the GPX plugin can only handle gcode files, the printer can only handle x3g files. So, if you, like me, are used to printing via a FlashAir card on the printer, you're used to x3g files and will forget that you have to use gcode files instead when printing from local storage. OOPS!

This could be fixed by having the GPX plugin simply check for this condition and handle it gracefully. It would be far more intuitive. Should this be wikified, @foosel?

What exactly? Do you mean turning your port here into a wiki or putting the GPX vs GCODE think on the Flashair FAQ entry?

Probably this post, since the error message is completely unintuitive, and the error is easy to make for anyone used to printing to on a printer running Sailfish.