Mw.col.find_cards (and AnkiConnect findCards) returns empty for is:due from add-on context, but Anki Browser works (Anki 25.02.6 macOS)

Hi everyone,

I’m encountering a strange issue with my Anki setup and would appreciate any insights.

Anki Version: 25.02.6 (6381f184) Python 3.9.18 Qt 6.6.2 PyQt 6.6.1

AnkiConnect Version (when tested):** Latest from AnkiWeb (code 2055492159, updated 2025-02-25). [Edit: I have since removed AnkiConnect to simplify testing with my own add-on, but the core issue persists with direct mw.col.find_cards calls.]

When querying for due cards from a specific deck (e.g., “Cell and Molecular Biology”) using mw.col.find_cards(‘deck:“Cell and Molecular Biology” is:due limit:10’) from within a Python Anki add-on context, the call returns an empty list . This also occurs for is:new queries.

This is despite the following working correctly:

  1. Anki Browser GUI: Searching deck:“Cell and Molecular Biology” is:due in Anki’s own browser shows many due cards (hundreds, in fact, with due dates in the past relative to my system clock of June 2025).

  2. Direct AnkiConnect findCards Test (when AnkiConnect was installed): A fetch call from a simple local HTML page (127.0.0.1) to AnkiConnect’s findCards action with the query deck:“Cell and Molecular Biology” is:due successfully returned 378 card IDs.

  3. Other API Calls from Add-on Context: My custom Python add-on can successfully make other internal Anki calls (e.g., get Anki version) and serve them via its local HTTP server.

Troubleshooting Done:

The issue occurs even with a brand new, clean Anki profile and a very simple test deck with one verifiably due card.

My custom add-on (MyCardServer) correctly handles the RepeatedScalarContainer by converting its contents to a Python list of integers before JSON serialization

The custom add-on’s HTTP server is running and responding to basic requests (like a /version endpoint).

CORS is correctly configured for my Chrome extension ID and 127.0.0.1.

The problem seems specific to mw.col.find_cards when used with is:due or is:new from an add-on, for certain decks/profiles, on this Anki build. The query mw.col.find_cards(‘deck:“Deck Name”’) (without is:due or is:new) does return all card IDs from the deck successfully via my add-on.

Has anyone encountered a similar discrepancy where mw.col.find_cards(‘is:due’) behaves differently when called from an add-on compared to the Anki Browser GUI? Are there any known issues or specific considerations for programmatic is:due / is:new queries in this environment?

My goal is to reliably fetch due/new cards from an add-on for an external Chrome extension

Any advice or things to investigate further would be greatly appreciated!

Thanks

Tried in the debug console, with zero add-ons installed?

Use TRACESQL=1 to see in a terminal exactly what is being searched for.

Hi everyone I found a work around:

I had my custom Anki add-on (MyCardServer) implement the following logic for a /get_daily_cards endpoint:

  1. Fetch all non-suspended/buried card IDs from the target deck using a simple query: cids = mw.col.find_cards(f’deck:“{deck_name}” -is:suspended -is:buried’).

  2. Iterate through these cids in Python.

  3. For each card (card = mw.col.get_card(cid)):

  • Check card.type == 0 to identify “new” cards.

  • Check card.queue (1, 2, or 3) and card.due (against mw.col.sched.today for reviews or time.time() for learning cards) to manually identify “due” cards.

  1. Collect these manually filtered lists of new and due card IDs and return them via JSON.

This manual filtering approach in Python successfully provides my external Chrome extension with the correct sets of due and new card IDs.

I’m more interested in why it was behaving differently. What happens if you try the steps I suggested above?