Wekan
Open source kanban board application built with Meteor
Alternative to: trello
v10.90
2026-08-13Binaries in these bundles
Each bundle carries a Node.js, a FerretDB and the MongoDB Database Tools. Which source has a given CPU varies from release to release - nodejs.org builds some architectures, unofficial-builds others, and the wekan/node-patches build the ones neither of them does - and not every source publishes a checksum. This is what went into this release, and which downloads were checked against a published SHA256.
| Bundle | Binary | From | Version | Checked | SHA256 |
|---|---|---|---|---|---|
| amd64 | FerretDB | wekan/FerretDB | v1.50.0 | verified | 9e001227107f244b… |
| amd64 | Node.js | nodejs.org | v24.19.0 | verified | 14b342e71204f811… |
| arm64 | FerretDB | wekan/FerretDB | v1.50.0 | verified | 4e63385a721f1c04… |
| arm64 | Node.js | nodejs.org | v24.19.0 | verified | 01443c1e1a29e531… |
| armhf | FerretDB | wekan/FerretDB | v1.50.0 | verified | e8c9f64f14433749… |
| armhf | Node.js | wekan/node-patches | v24.19.0 | verified | b55350f3071b765a… |
| armv6 | FerretDB | wekan/FerretDB | v1.50.0 | verified | 11cf98ff5e2f0ed4… |
| armv6 | Node.js | wekan/node-patches | v24.19.0 | verified | 128ded0cda638c1f… |
| armv7 | FerretDB | wekan/FerretDB | v1.50.0 | verified | e8c9f64f14433749… |
| armv7 | Node.js | wekan/node-patches | v24.19.0 | verified | 8dbe0a9aa8550ad5… |
| i386 | FerretDB | wekan/FerretDB | v1.50.0 | verified | fc8a8d0e01748a20… |
| i386 | Node.js | wekan/node-patches | v24.19.0 | verified | 3b0b3bbfe27daf58… |
| mac-arm64 | FerretDB | wekan/FerretDB | v1.50.0 | verified | 0864e1d8c74a0cd4… |
| mac-arm64 | Node.js | nodejs.org | v24.19.0 | verified | 3f1cf157479c1480… |
| mac-x64 | FerretDB | wekan/FerretDB | v1.50.0 | verified | 83d6fde4b70088a8… |
| mac-x64 | Node.js | nodejs.org | v24.19.0 | verified | d35e95230f46f6f0… |
| ppc64le | FerretDB | wekan/FerretDB | v1.50.0 | verified | 9a3aec0a01e50f54… |
| ppc64le | Node.js | nodejs.org | v24.19.0 | verified | c510c6ce12f07010… |
| riscv64 | FerretDB | wekan/FerretDB | v1.50.0 | verified | 71c33d684350893e… |
| riscv64 | Node.js | unofficial-builds.nodejs.org | v24.19.0 | verified | cd1f14af28121480… |
| s390x | FerretDB | wekan/FerretDB | v1.50.0 | verified | dc8dfb6f11f5188f… |
| s390x | Node.js | nodejs.org | v24.19.0 | verified | a4792e65962ffa0a… |
| win-arm64 | FerretDB | wekan/FerretDB | v1.50.0 | verified | e210ec18a59a24c2… |
| win-arm64 | Node.js | nodejs.org | v24.19.0 | verified | 8502f4a50b458d4c… |
| win64 | FerretDB | wekan/FerretDB | v1.50.0 | verified | d232f53684f84bea… |
| win64 | Node.js | nodejs.org | v24.19.0 | verified | 57f71ab3652e797d… |
A row saying no checksum published is not a failed check - it is a source that publishes nothing to check against. Those are the ones worth fixing at the source.
v10.90 2026-08-13 WeKan ® release
In short: things that were reported this week, and one of them is data
coming back from the dead: previously archived cards, some years old,
reappeared in the top swimlane because the schema upgrade treated an archived
swimlane as breakage. The board Excel export answered nothing at all — it
had been broken since a dependency bump, and the route swallowed the failure so
the browser waited forever. A .drawio attachment was stored as .bin,
unopenable, and could not even be renamed back. The board’s watch popup did
nothing for anybody who reaches a board through an organisation, a team or an
email domain, and said nothing either. And when the snap cannot read an old
MongoDB, it now prints what each reader actually said and where to download a
MongoDB that can. Below that: two release-tooling fixes from the v10.89 run.
The binaries below are carried over from v10.89 and have NOT been checked
against a newer build; releases/provenance-table.sh prints the real table
from the provenance each build job records.
| Platform | Binary | From | Version | SHA256 |
|---|---|---|---|---|
| amd64 | Node.js | nodejs.org | v24.19.0 | 14b342e71204f811bde6153be8e04b62aef63c236fef92b55f9c83154b409647 |
| amd64 | FerretDB | wekan/FerretDB | v1.49.0 | 7c74941ff043f26aa4411ef5065d6b2d0766e369fc2a4458364c2f5571c12762 |
| arm64 | Node.js | nodejs.org | v24.19.0 | 01443c1e1a29e531ccad5a46fefa6df490d2189c49f7955904aecdbb0fe86fdc |
| arm64 | FerretDB | wekan/FerretDB | v1.49.0 | 092132531555a39eac12566240a5f1ed02f62148b2dca0540a74c68e5957f6b5 |
| armhf | Node.js | wekan/node-patches | v24.19.0 | b55350f3071b765a98ed66fdc410657ff168a937935057077fd7ab33cb30b9aa |
| armhf | FerretDB | wekan/FerretDB | v1.49.0 | 144404fb9793dc8e039874812f4e2cb3e6d8b1df0ffdbe50254e7790a342a2f4 |
| armv6 | Node.js | wekan/node-patches | v24.19.0 | 128ded0cda638c1f144eadb23ad249889515df017d298fd49c8faf3db110f0f1 |
| armv6 | FerretDB | wekan/FerretDB | v1.49.0 | 7c27b2c15448709a24eace9b3c951c62fbe33413f7d20d56cb5520f4436efe2d |
| armv7 | Node.js | wekan/node-patches | v24.19.0 | 8dbe0a9aa8550ad5275c5538ebf868eb2037f0c4d9cccbe319f63b7e5854cd45 |
| armv7 | FerretDB | wekan/FerretDB | v1.49.0 | 144404fb9793dc8e039874812f4e2cb3e6d8b1df0ffdbe50254e7790a342a2f4 |
| i386 | Node.js | wekan/node-patches | v24.19.0 | 3b0b3bbfe27daf583b3a0f432efacc508407a012cdd9e8847250e7c015565bac |
| i386 | FerretDB | wekan/FerretDB | v1.49.0 | 1f70cb1687411b2a0fa9ac3b5bfc8c4ed9ce25ec2ddfa17e6fd3efb38136a39c |
| mac-arm64 | Node.js | nodejs.org | v24.19.0 | 3f1cf157479c1480352083105e13faf9d008ede98e7e157746b6df940d197b94 |
| mac-arm64 | FerretDB | wekan/FerretDB | v1.49.0 | 576364db59dfce3ba564b9a3e484496eb57f95d76d2007b9f83241acdbd2f4fa |
| mac-x64 | Node.js | nodejs.org | v24.19.0 | d35e95230f46f6f0751df497c56622c6735e05d5e1fb1630996a005b9d328fe4 |
| mac-x64 | FerretDB | wekan/FerretDB | v1.49.0 | 37d70cd90aad6d3867b6686507ff1888f1edf6791818c31d014d130e8f39fc14 |
| ppc64le | Node.js | nodejs.org | v24.19.0 | c510c6ce12f07010f771e6edb22a3fe23f4f2e6f40b1ffd4941aed0646a0d8b3 |
| ppc64le | FerretDB | wekan/FerretDB | v1.49.0 | 7c61d4853d5163ad8761449d693fd458ebbb8611a2351c718014876242c5b1fb |
| riscv64 | Node.js | unofficial-builds.nodejs.org | v24.19.0 | cd1f14af2812148002f58b58a5f9af512a50e3b8e8c148e0db44019dcb68edfd |
| riscv64 | FerretDB | wekan/FerretDB | v1.49.0 | bd4912da70f5e6c1475ab989668c76b4ab7db4ee06c44357693df64f5e1d0e0b |
| s390x | Node.js | nodejs.org | v24.19.0 | a4792e65962ffa0af42627aacf1122a60c3c88dbf4e4184f06820d66f9da8ba4 |
| s390x | FerretDB | wekan/FerretDB | v1.49.0 | no checksum published |
| win-arm64 | Node.js | nodejs.org | v24.19.0 | 8502f4a50b458d4cc38ed8f2001556c2cd239d464920f74017926ccb1e1c157f |
| win-arm64 | FerretDB | wekan/FerretDB | v1.49.0 | 792166623e774b0af2aced31ed3ae39f545ca5268dc4c2b8d1a329228ff52cbc |
| win64 | Node.js | nodejs.org | v24.19.0 | 57f71ab3652e797d84acddc79c81cc9ff1c6ddb2a1974cdb83f00fee9bff4c73 |
| win64 | FerretDB | wekan/FerretDB | v1.49.0 | f42c50aa84095a9616b00f27a584c66b7bf79e3b109450c62a5f146ba3c85478 |
This release fixes the following bugs:
Recovering a snap that has two copies of its data
Two commands for a snap that is serving the older of its two copies. Thanks to waltermhl, lukechao and xet7.
From #6583: “The migration and the update to 10.83 startet at 11.08.2026 at 6:35 pm and migration failed. Now we just see the old data from a migration we did in july 2026. … Which steps exactly could we do, to restore the database with our most recent data?”
Everything needed to answer that already existed — db-eval evidence,
database-choose.mjs, database-merge-missing.mjs, database-autopick — and
none of it was a command anybody could run. snap run wekan.problems answered
“No problems detected”, which is true of the things it checks and no help at
all here.
sudo snap run wekan.database-compare # what does each copy hold?
sudo snap run wekan.database-merge # bring the missing documents across
compare starts each database on a temporary port, counts its documents and finds the newest moment its data carries, and prints both sides — the running WeKan is not disturbed, and nothing is written. A file timestamp cannot answer this question: starting a database moves its files, and a file written a minute ago may hold nothing anybody typed.
merge inserts the documents that exist in the MongoDB copy and not in the
FerretDB one. It overwrites nothing, deletes nothing, and reads the MongoDB
files only — so it is safe to run without first knowing which copy is “right”.
That is WeKan’s own design doing the work: the history is append-only, so
merging can only ADD to what a card shows, and the work that was stranded
becomes readable in that card’s History. What it does not do is reconcile two
edits of the same card; the served copy’s version stands, and the other stays
where it is. It asks for a copy of $SNAP_COMMON first, with the command, and
takes --dry-run.
The removed snap run wekan.database switch is gone from the core26 snapcraft
file as well, where it had been left behind.
Boards - what shows on them, and what quietly does not.
Cards archived years ago no longer reappear in the top swimlane. Thanks to xet7.
Reported by email: “Previously archived cards (some several years old) have reappeared. These cards have incorrectly been placed in the top swimlane.”
Archiving a swimlane is how a whole swimlane is put away: its cards stay where
they are, archived: false, out of sight because the swimlane is. The schema
upgrade’s swimlane rescue read that as breakage and moved every such card to
the board’s first VISIBLE swimlane — so work anybody had ever archived that way
came back, years later, at the top of the board.
A card is orphaned when its swimlane does not exist, or belongs to another
board. That is #1959, and it is
still rescued. The other issue the sweep cited,
#1971, is about cards added in
List view landing in an archived swimlane — and that is fixed where cards are
created, by getDefaultSwimline() picking a non-archived swimlane. It never
needed a sweep over data somebody archived on purpose.
The two guards that pinned the sweep now pin the opposite, each carrying the reason, and a board whose every swimlane is archived is left exactly as it is.
The watch popup works for everyone who can open the board, and says so when it refuses. Thanks to xet7.
Reported by email, with a screenshot of the Ändra bevaka popup: “Silent does not respond. If we try to change it does not change. Nothing happens.”
Driven against a running WeKan, the popup works for a board member — the level is written, the check mark moves, the popup closes — and does nothing at all for anybody else:
login as non-member admin: ok
watch -> ERROR error-board-notAMember
A board is shared four ways: membership, an organisation, a team, and (since
#5850) an email domain. Only the
first puts anybody in members, and the watch method asked hasMember().
Everyone reaching a board through an org, a team or a domain could open it, see
the button, and be refused the moment they used it. It asks whether the user may
see the board now, through the same selectors the publications use — so a
watch can never be granted where the board is not visible, and a revoked share
still is not.
The other half is why nobody could tell: the popup closed on success and did
nothing otherwise, so a refusal was indistinguishable from a dead button. It
reports the reason now — the watch feature being off in the Admin Panel, or the
board not being visible — and error-watch-disabled, thrown since #5820 but
never translated, exists as a string.
Cards and attachments - what a card holds, and getting it back out.
An unknown file type is no longer renamed to .bin, and a stuck attachment can be repaired. Thanks to rmb82 and xet7.
#6589: a .drawio upload was
stored and displayed as .bin, could not be opened, and could not be renamed
back either — renameAttachment threw ENOENT. Two faults.
The name. A browser sends application/octet-stream for a type it does not
know, and the upload-time “correct the extension to the type” step took that
literally: mime.extension('application/octet-stream') is bin, so
sso-proconnect-keycloak.drawio became …drawio.bin. Every unrecognised format
— .drawio, .kdbx, .ova, anything new — went the same way. An uninformative
type now yields no extension at all, while a type that does say something still
corrects the name, which is what that step is for.
The rename. The recorded versions[].path and the file on disk had
diverged, and rename used the recorded path alone:
Error: ENOENT: no such file or directory, rename
'/data/files/attachments/6a7d66369c6aee799e857d36.drawio' -> ...
while the READER already searched every layout WeKan has used and found the file. That search is a method now, and reading, renaming and deleting all use it — so an attachment that can be read can also be repaired. When there really is no file, the error names the attachment instead of a path nobody recognises.
A card containing an onenote: link no longer stops a whole board from rendering. Thanks to titver968 and xet7.
#6590: “A board gets stuck
indefinitely on the loading animation (three dots) for all users”, traced to
one card whose description and checklist item held
onenote:///path/to/file.one#section-id={GUID}.
It is #6588 from the other end —
the same this.__schemas__[...].validate is not a function out of linkify-it 6,
reported as a board nobody could open rather than a card nobody could open — and
it was fixed on 2026-08-12. The regression test now renders that exact string,
in a description and in a checklist item, and pins that the {GUID} stays text
rather than being swallowed into a link.
Exporting a board - the format that answered nothing.
The Excel export produces a file again, and a failure answers instead of hanging. Thanks to titver968 and xet7.
#6591: “Board Settings -> Export board -> export/Excel didn’t work”. Reproduced against a running WeKan — CSV and JSON of the same board answered 200, and Excel never answered at all:
csv: HTTP 200 4758b
json: HTTP 200 4491b
excel: Operation timed out after 30002 ms with 0 bytes received
with nothing in the server log. Two faults, either of which hangs the browser on its own.
The zip. exceljs 4.7.3’s streaming writer calls archiver the way archiver 7
was called — Archiver('zip', opts) — and WeKan moved to archiver 8 for the
low-memory backup zips. archiver 8 is ESM and exports classes, so that is
TypeError: Archiver is not a function, and the export has been broken since
the bump. Supplying the missing factory does not rescue it either: archiver 8’s
readable-stream then refuses the objects exceljs appends. So the export asks
what archiver exports and, when it cannot stream, it uses a buffered writer
with the same API — the path this export used before it was made streaming.
Bounded memory is what is lost, not the export.
The silence. The route called exporterExcel.build(res) without awaiting
it, so the rejection went nowhere: no 500, no log line, and a response that was
never written or ended. Every sibling route awaits; this one did not. It does
now, and a failure answers 500 with the reason.
The snap - when it cannot read the database it is asked to migrate.
Each reader says why it refused the data, and the page says where to get an old MongoDB. Thanks to mueschel and xet7.
From #6585, a log that says everything except the useful part:
[migration] mongod 7 could not open the data; trying the bundled mongod 5.0 ...
[migration] mongod 7 could not open the data; trying the bundled mongod 4.2 ...
[migration] The database files were made by an older MongoDB
(MongoDB 4.2 or earlier can still read them).
Every reader was tried, each of them said something, none of it was shown — and the conclusion recommends the version that had just failed. mongod 7 names the version that can open the FORMAT; it cannot know the files are also damaged, or left locked by an unclean shutdown.
So each reader now prints its own last words when it does not open the data, the
“trying the bundled X” lines name the reader being tried instead of blaming
mongod 7 for all of them, and when mongod 7 asks for a version this snap
carries, the report says it was tried too and that --repair on a copy is
the usual next step.
And the other half of that report — “If you need us to run some external tools,
like an old mongodb, it would be good to provide a source for them” — the log
and the explanatory page now link mongodb.com’s download page and
fastdl.mongodb.org, name the docker run mongo:<version> one-liner, and spell
out mongod --dbpath / mongodump on a copy, never the original.
and fixes the following release-tooling bugs:
A snap that reached the Snap Store also reaches the GitHub Release. Thanks to xet7.
The v10.89 run published the armhf, ppc64el and s390x snaps and then failed on the next line:
Revision 3661 created for 'wekan' and released to
'beta', 'candidate', 'edge', and 'stable'
no git remotes found
Error: Process completed with exit code 1
Those jobs flatten history so the Launchpad push stays small, and the git remote
goes with it — so gh had nothing to infer the repository from. The snap was in
the store and not on the release, which reads like a failed build.
Every gh release upload, view and edit in every workflow now names the
repository, so the call does not depend on what the checkout looks like, and a
bare one fails the guard.
A Launchpad build that outlives its job says so, instead of just CANCELLED. Thanks to xet7.
v10.89’s riscv64 leg ran five hours and fifty minutes — its cap — with Launchpad
still printing Building: riscv64, and the run showed CANCELLED and nothing
else. What is true at that moment is worth saying: the Launchpad build is not
cancelled with the job, it keeps its name, and re-running the job reconnects to
the same build and downloads the snap rather than starting another one.
The cap is now 360 minutes, the maximum a hosted runner allows, and a cancelled job prints that explanation plus any Launchpad URL its logs carry.
Thanks to above GitHub users for their contributions and translators for their translations.