mirror of
https://github.com/plankanban/planka.git
synced 2026-07-16 05:53:57 +03:00
[Bug]: getCards endpoint doesn't seem to respect filterUserIds or filterLabelIds
#904
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @hwelch-fle on GitHub (Jan 27, 2026).
Where is the problem occurring?
I encountered the problem while interacting with the server (Backend)
What browsers are you seeing the problem on?
Other
Current behavior
It seems that the options for filtering cards from a list are possibly not working correctly (
nightlyversion). Here's someplankapyendpoint testing with the issues:This is using the raw endpoint to show that the issue seems to be with how the server is processing the request. I believe that the
filterListandfilterUserissues might be related to #1302 and #1487 since they're using that same regex for id validation. I'm not sure why thebeforeoption isn't working though. The validator seems to be written correctly as documented by the API:2c4369159b/server/api/controllers/cards/index.js (L151-L165)But it's not respecting the passed arguments. Could this also be failing with the
idvalidators?2c4369159b/server/utils/validators.js (L12-L13)Desired behavior
see above
Steps to reproduce
see above
Other information
Here's the goal for plankapy syntax using this endpopint:
@meltyshev commented on GitHub (Jan 28, 2026):
Hey! Thanks for reporting this.
We renamed these parameters to just
userIdsandlabelIdsto keep naming consistent across the project. That's probably why they're being ignored in thenightlyversion... If not, it'd be interesting to investigate further, but from my testing in PLANKA (since it uses the same API) - the endpoint itself returns the correct data for me.And regarding the
beforeparameter, I think I ran into the same issue when testing it via Postman. The original idea of sending a JSON structure as a single parameter doesn't seem to work - it's only decoded correctly when PLANKA sends it via websocket while emulating an HTTP request. I'll test further and see what can be done here.@hwelch-fle commented on GitHub (Jan 28, 2026):
Really odd... I did try testing again with those keys and I'm still getting the same issue of everything being returned. No server errors or anything, it's just not applying the filter...
Hmmm... I think this same issue is causing stopwatches to fail out too. I'm formatting the request properly, but it's rejecting anything I give it. I tried a string, JSON, and raw bytes using multipart-form encoding.
I'll keep playing around with it and see if its something stupid I'm doing (likely), and once I exhaust that bottomless well of possibility I'll try and run through what's happening server side and see if it's some improperly formatted handler or something.
@hwelch-fle commented on GitHub (Jan 28, 2026):
@meltyshev It was indeed a footgun. I build the path schema off your openapi/swagger doc and that was out of date. All other endpoints allow for arbitrary keys, but parameter endpoints enforce parameterization for
GETrequests to keep them out of the body. So the keys were being dropped -_-It was the second change that was causing the silent failure. That pattern is enforced to prevent parameter args from being passed in the body.
@meltyshev commented on GitHub (Jan 28, 2026):
Oops, sorry about the name changes 😄 but no more changes are expected, so this should be the last issue related to that.
I've also just tested how to pass the
beforeparameter via GET and figured out that it needs to use a nested structure like this:?before[listChangedAt]=2024-01-01T00:00:00.000Z&before[id]=1357158568008091269(I assume it should be handled automatically byhttpx?).When trying to pass it as JSON like
?before={"listChangedAt":"2024-01-01T00:00:00.000Z","id":"1357158568008091269"}- it gets parsed as a string and fails validation.@meltyshev commented on GitHub (Jan 28, 2026):
And we probably need to update the definition of the GET parameters in Swagger.
Instead of:
It should be something like:
UPD: not sure why, but https://editor.swagger.io shows an error when using
style: deepObject, so it's probably better to define these parameters explicitly like this:@hwelch-fle commented on GitHub (Jan 28, 2026):
Is there a reason it needs to be passed as a deepObject? Why not just make it two parameters
beforeListChangedAtandbeforeCardId.Just seems off that this would be the only instance of that style of parameter in the whole API.
Plus that syntax for name means it becomes an invalid property name in Python and means I need to add another edge case to the schema parser that uses the functional style object declaration 😅
@meltyshev commented on GitHub (Jan 28, 2026):
Yep, there's a reason for that. With two separate parameters it's hard to understand that they actually work together as a single cursor. If you just see two different parameter names, it's not obvious that the results are first ordered by
listChangedAt, and then (only if multiple items have the samelistChangedAt) theidfield is used to continue the range.This was added when we implemented bulk archiving cards from the Closed list - all cards (and there can be 100+ of them) can be moved to the Archive list with the same
listChangedAttimestamp. To load 50 cards and then the next 50, we need to pass bothlistChangedAtand the last cardidtogether, otherwise (if we pass onlylistChangedAt) we would either load the same cards again or skip the next batch.We use the same approach in the Pro version as well. For example, when lazily loading users (where fetching and filtering is done server-side to handle thousands of users) - we first sort by the
namefield, and since multiple users can share the same name, then useidas a secondary field to keep pagination consistent.@hwelch-fle commented on GitHub (Jan 28, 2026):
This makes a lot more sense now. I was under the impression that
beforewas meant to get cards that were moved before a date or are before a specific card in a list.I might end up just not exposing this in the public API since it seems to be more for internal management of lists. It would be easy enough to just grab all board cards from
board.includedand build something more akin to activity filtering that way.