So I ended up getting this to work. It turns out the plugin parameters are required (even though they aren't marked as such in the docs):
curl -X GET 'https://mymoodle.edu/webservice/rest/server.php? wstoken=<token>&moodlewsrestformat=json&wsfunction=mod_assign_save_grade& assignmentid=1&userid=4&grade=3&attemptnumber=-1&addattempt=0&workflowstate=graded&applytoall=0'& plugindata%5Bassignfeedbackcomments_editor%5D%5Btext%5D=test& plugindata%5Bassignfeedbackcomments_editor%5D%5Bformat%5D=1&plugindata%5Bfiles_filemanager%5D=0'
Which still poses the questions:
- Should these parameters be marked as required if you get a "invalid parameter error" without them?
- Can anyone tell me what the 'plugindata[assignfeedbackcomments_editor][format]' parameter does?
And it would still be great to know if there are more detailed debugging logs for incoming failed WS calls anywhere.
P.S. My Python wrapper code can be found at https://github.com/asayler/moodle-ws-python/blob/master/ws.py.