AnkiconnectAndroid icon indicating copy to clipboard operation
AnkiconnectAndroid copied to clipboard

Error when adding a card with "suspend new cards" on

Open curtisbarnard opened this issue 11 months ago • 6 comments

Thanks a bunch for the work on this. I just got it up and running with Firefox Android and Yomitan and was able to add some cards to my Anki deck. I did notice that if I have the "Suspend new cards" option turned on in yomitan that I get an error in the Yomitan popup after the card is added:

An error occured:

Anki error: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 14 path $com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 14 path $ 	at com.google.gson.JsonParser.parseReader(JsonParser.java:66) 	at com.google.gson.JsonParser.parseString(JsonParser.java:47) 	at com.kamwithk.ankiconnectandroid.routing.AnkiAPIRouting.findRouteHandleError(AnkiAPIRouting.java:106) 	at com.kamwithk.ankiconnectandroid.routing.APIHandler.chooseAPI(APIHandler.java:33) 	at com.kamwithk.ankiconnectandroid.routing.RouteHandler.get(RouteHandler.java:70) 	at fi.iki.elonen.router.RouterNanoHTTPD$DefaultStreamHandler.post(RouterNanoHTTPD.java:100) 	at fi.iki.elonen.router.RouterNanoHTTPD$UriResource.process(RouterNanoHTTPD.java:386) 	at fi.iki.elonen.router.RouterNanoHTTPD$UriRouter.process(RouterNanoHTTPD.java:596) 	at fi.iki.elonen.router.RouterNanoHTTPD.serve(RouterNanoHTTPD.java:671) 	at fi.iki.elonen.NanoHTTPD$HTTPSession.execute(NanoHTTPD.java:945) 	at fi.iki.elonen.NanoHTTPD$ClientHandler.run(NanoHTTPD.java:192) 	at java.lang.Thread.run(Thread.java:1012) Caused by: com.google.gson.stream.MalformedJsonException: Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 14 path $ 	at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1597) 	at com.google.gson.stream.JsonReader.checkLenient(JsonReader.java:1404) 	at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:542) 	at com.google.gson.stream.JsonReader.peek(JsonReader.java:425) 	at com.google.gson.JsonParser.parseReader(JsonParser.java:61) 	... 11 more 

Log debug info to console

I checked my Anki deck and the card got added fine and it has all the correct fields filled in (expression, reading, audio, tags, etc.), the only issue is that it is not in a suspended state.

I'm not sure if this is a known issue, but I wanted to report it anyway. It's not critical to my study workflow, but would be nice to have if anyone gets around to it.

curtisbarnard avatar Feb 07 '25 23:02 curtisbarnard

Hmmm I never used this feature and can't remember much about it

Have you checked on TMW whether others experience it so we can check whether it's a problem with your setup or just a general bug in the code atm?

KamWithK avatar Feb 16 '25 01:02 KamWithK

@KamWithK sorry what is TMW?

curtisbarnard avatar Feb 18 '25 15:02 curtisbarnard

@KamWithK sorry what is TMW?

The More Way is a Discord community for language learning where most users of my learn Japanese tools are from

KamWithK avatar Feb 18 '25 22:02 KamWithK

Seems like yomitan uses the "suspend" AnkiConnect API for this option, so that after it adds a new card it sends another request to suspend it: https://github.com/yomidevs/yomitan/blob/d2fd7ec796bf3329abd6b92f2398e734d5042423/ext/js/display/display-anki.js#L784

Shouldn't be too much to add support for the API, let me see what I can do.

drakargx avatar Apr 17 '25 14:04 drakargx

Looked into it more and it seems like there's not an easy way to do this.

Problem is the AnkiDroid's API doesn't actually have a way to get the Card ID. When Yomitan adds a card with the "suspend new cards" feature, it uses two requests that AnkiConnect provides:

  • findCards - with the note ID it obtained after the card was added
  • suspend - with the card IDs it obtained from findCards

AnkiConnect Android doesn't support either request currently. It seems that the developers for AnkiDroid expected that if a card should be suspended, you would first use the note ID to get its card ordinals, and then supply both the note ID and the ordinals to suspend.

Right now I'm thinking there's two options forward if support would get added:

  1. The "cheating" solution is to save the note IDs in the request, and give Yomitan the ordinals for the cards as the response from findCards. When it requests suspend right after, we use the saved note ID and the cardinals to suspend the cards. I don't like this solution...
  2. AnkiDroid API is changed to allow for obtaining the card ID. It seems there is a pull request to add this, but it hasn't had any activity since November last year.

I think best steps forward is to hope that the API gets changed.

Edit: After making this post I asked about the linked pull request in the Anki discord - seems like there is a fair chance it (or something like it) could make it in a future release.

I tested some changes that adds both findCards and suspend with the AnkiDroid PR and it worked, so just need to wait for an update on their side.

drakargx avatar Apr 19 '25 22:04 drakargx

Looked into it more and it seems like there's not an easy way to do this.

Problem is the AnkiDroid's API doesn't actually have a way to get the Card ID. When Yomitan adds a card with the "suspend new cards" feature, it uses two requests that AnkiConnect provides:

* `findCards` - with the note ID it obtained after the card was added

* `suspend` - with the card IDs it obtained from `findCards`

AnkiConnect Android doesn't support either request currently. It seems that the developers for AnkiDroid expected that if a card should be suspended, you would first use the note ID to get its card ordinals, and then supply both the note ID and the ordinals to suspend.

Right now I'm thinking there's two options forward if support would get added:

1. The "cheating" solution is to save the note IDs in the request, and give Yomitan the ordinals for the cards as the response from `findCards`. When it requests `suspend` right after, we use the saved note ID and the cardinals to suspend the cards. I don't like this solution...

2. AnkiDroid API is changed to allow for obtaining the card ID. It seems there is a [pull request](https://github.com/ankidroid/Anki-Android/pull/17345) to add this, but it hasn't had any activity since November last year.

I think best steps forward is to hope that the API gets changed.

Edit: After making this post I asked about the linked pull request in the Anki discord - seems like there is a fair chance it (or something like it) could make it in a future release.

I tested some changes that adds both findCards and suspend with the AnkiDroid PR and it worked, so just need to wait for an update on their side.

It looks a lot like that PR will eventually make it in given it just got reviewed a few days ago

I'd personally suggest just cycling back to this in a month or so and hopefully by then it'll be merged and we can get it working then

KamWithK avatar Apr 27 '25 09:04 KamWithK