Releases: fedify-dev/fedify
Fedify 2.0.3
Released on March 3, 2026.
@fedify/postgres
-
Fixed
PostgresMessageQueue.listen()crashing the process when a malformedNOTIFYpayload is received.Temporal.Duration.from()was called without error handling, so an invalid duration string caused an unhandledRangeErrorthat propagated through the postgres driver. TheNOTIFYcallback is now wrapped in atry–catchthat logs the error and falls back to an immediate poll. [#594] -
Fixed
PostgresMessageQueue.listen()permanently stalling all message processing when a message handler hangs indefinitely (e.g., due to an unresponsive remote server). TheserializedPollmechanism chains everypoll()invocation onto a single promise, so a single hung handler blocked the entire queue permanently. Handler invocations are now wrapped with a configurable timeout (default: 60 seconds) via the newhandlerTimeoutoption inPostgresMessageQueueOptions. When a handler exceeds the timeout, it is treated as an error and the poll loop moves on, preventing permanent stalls. [#595]
Fedify 2.0.2
Released on February 27, 2026.
@fedify/fedify
- Removed the deprecated third and fourth parameters (
signedKeyandsignedKeyOwner) fromAuthorizePredicateandObjectAuthorizePredicate. These parameters were deprecated since Fedify 1.5.0 in favor ofRequestContext.getSignedKey()andRequestContext.getSignedKeyOwner()methods, but were mistakenly left in the Fedify 2.0.0 release. The internal handler code that eagerly calledgetSignedKey()andgetSignedKeyOwner()before invoking the predicate has also been removed; predicates should now call those methods themselves when needed. [#473, #590]
Fedify 2.0.1
Released on February 24, 2026.
@fedify/cli
- Fixed
fedifycommand hanging indefinitely when invoked as an executable (e.g., vianpx @fedify/cliornpm exec -- fedify) on Linux. The shebang line#!/usr/bin/env node --disable-warning=ExperimentalWarningwas passingnode --disable-warning=ExperimentalWarningas a single argument toenv, which caused an infinite exec loop on Linux because the kernel passes all shebang arguments as one string. Fixed by usingenv -Sto properly split arguments:#!/usr/bin/env -S node --disable-warning=ExperimentalWarning.
@fedify/postgres
-
Fixed
PostgresMessageQueue.listen()permanently stopping message processing whenpoll()throws (e.g., transient PostgreSQL errors or handler failures).listen()now catches polling errors for subscribe, notify, and interval-triggered polls, logs them, and retries on subsequent triggers instead of terminating the listener. [#581] -
PostgresMessageQueue.initialize()now creates an index on thecreatedcolumn (idx_{table}_created) to improve dequeue query performance under backlog growth. [#581]
Fedify 2.0.0
Released on February 22, 2026.
@fedify/fedify
-
Remove
contextLoaderoption (which was deprecated) fromFederationOptionsinterface in favor ofcontextLoaderFactoryoption for better flexibility. [#376, #445 by Hasang Cho] -
Migrated from @phensley/language-tag package and its
LanguageTagclass to the standardizedIntl.Localeclass for representing language tags. [#280, #392 by Jang Hanarae]- The
LanguageString.languageproperty is nowLanguageString.localeand is of typeIntl.Localeinstead ofLanguageTag. - The
LanguageStringconstructor now accepts either anIntl.Localeobject or a string for the language parameter. - The
Link.languageproperty is now of typeIntl.Localeinstead ofLanguageTag. - Removed the
@phensley/language-tagdependency.
- The
-
Remove
documentLoaderoption (which was deprecated) fromFederationOptionsinterface in favor ofdocumentLoaderFactoryoption for better flexibility. [#376, #393 by Hasang Cho] -
Remove
CreateFederationOptions<TContextData>interface (which was deprecated since 1.6.0). UseFederationOptions<TContextData>instead. [#376] -
Remove
fetchDocumentLoader()function (which was deprecated since 0.14.0). UsegetDocumentLoader()from@fedify/vocab-runtimeinstead. [#376] -
Remove
{ handle: string }parameter form fromsendActivity(),forwardActivity(),getDocumentLoader(), andParseUriResult. Use{ identifier: string }or{ username: string }instead. [#376] -
Changed NodeInfo
software.versionfield type fromSemVertostringto properly handle non-SemVer version strings in accordance with the NodeInfo specification. [#366, #433 by Hyeonseo Kim]- The
parseNodeInfo()function now returns version asstringinstead ofSemVerobject. - The
Software.versionfield is now ofstring(was ofSemVer). - Removed
parseSemVer()andformatSemVer()functions. - Updated related CLI tools and documentation.
- The
-
Federation dispatchers are now only triggered when the request accepts ActivityPub-compatible content types. This improves compatibility with applications that serve both HTML and ActivityPub content from the same URLs. [#434 by Emelia Smith]
- Actor, object, and collection dispatchers will no longer be called for requests with
Accept: text/htmlor other non-ActivityPub content types. - The
notAcceptablecallback is now triggered at the middleware level before dispatchers are invoked. - If your application relies on dispatchers being called regardless of
Acceptheader, you may need to adjust your routing logic.
- Actor, object, and collection dispatchers will no longer be called for requests with
-
Changed the default activity idempotency strategy from
"per-origin"to"per-inbox"to align with standard ActivityPub behavior. [#441]- Activities are now deduplicated per inbox by default, allowing the same activity ID to be processed once per inbox independently.
- The previous
"per-origin"strategy (deduplicate per receiving server) can still be explicitly configured using.withIdempotency("per-origin"). - This change ensures proper delivery of activities to multiple inboxes on the same server, fixing issues where activities were incorrectly deduplicated globally.
-
Separated modules from
@fedify/fedify/runtimeto improve modularity and reduce coupling between vocabulary generation and core federation functionality. [#444, #451 by ChanHaeng Lee]- Modules related to ActivityPub vocabulary generation have been extracted into the new
@fedify/vocab-runtimepackage. - Other utility modules from
@fedify/fedify/runtimehave been reorganized into the@fedify/fedify/utilsdirectory within the main package. - Updated import paths throughout the codebase to reflect the new module organization.
- Modules related to ActivityPub vocabulary generation have been extracted into the new
-
Deprecated the
@fedify/fedify/runtimemodule in favor of the new@fedify/vocab-runtimepackage. The@fedify/fedify/runtimemodule now re-exports all exports from@fedify/vocab-runtimefor backward compatibility, but will be removed in a future version. Please migrate to@fedify/vocab-runtimedirectly. [#560] -
The
KvCacheParameters.rulesoption's type became[string | URL | URLPattern, Temporal.Duration | Temporal.DurationLike][](was[string | URL | URLPattern, Temporal.Duration][]). -
The
@fedify/fedify/x/*modules are removed. Also, there are no Fresh integration for now. [#391 by Chanhaeng Lee]- Removed
@fedify/fedify/x/cfworkersin favor of@fedify/cfworkers. - Removed
@fedify/fedify/x/denokvin favor of@fedify/denokv. - Removed
@fedify/fedify/x/honoin favor of@fedify/hono. - Removed
@fedify/fedify/x/sveltekitin favor of@fedify/sveltekit. - Removed
@fedify/fedify/x/fresh(Fresh integration). [#466]
- Removed
-
Deprecated the
@fedify/fedify/vocabmodule in favor of the new@fedify/vocabpackage. The@fedify/fedify/vocabmodule now re-exports all exports from@fedify/vocabfor backward compatibility, but will be removed in a future version. Please migrate to@fedify/vocabdirectly. [#437, #517 by ChanHaeng Lee] -
The
KvStore.list()method is now required instead of optional. This method was added as optional in version 1.10.0 to give existing implementations time to add support. All officialKvStoreimplementations already support this method. [#499, #506] -
Added
orderingKeyoption toMessageQueueEnqueueOptionsinterface for ordered message delivery. Messages with the same ordering key are guaranteed to be processed in the order they were enqueued, while messages with different ordering keys can be processed in parallel. This helps prevent race conditions when processing related activities (e.g., ensuring aDeleteactivity is processed after aCreateactivity for the same object). [#536, #538, #540, #544]- Added
MessageQueueEnqueueOptions.orderingKeyproperty. - All properties in
MessageQueueEnqueueOptionsare nowreadonly. InProcessMessageQueuenow supports theorderingKeyoption.- Added
SendActivityOptions.orderingKeyoption to ensure ordered delivery of activities for the same object. When specified, activities with the sameorderingKeyare guaranteed to be delivered in order to each recipient server.
- Added
-
Added
Federatable.setOutboxPermanentFailureHandler()method to handle permanent delivery failures (such as410 Goneor404 Not Found) when sending activities to remote inboxes. This allows applications to clean up unreachable followers and avoid future delivery attempts to permanently failed inboxes. [#548, #559] -
Added
permanentFailureStatusCodesoption toFederationOptionsto configure which HTTP status codes are treated as permanent delivery failures. By default,404and410are treated as permanent failures. [#548, #559] -
Added
SendActivityErrorclass, a structured error that is thrown when an activity fails to send to a remote inbox. It includes the HTTP status code, the inbox URL, and the response body, making it easier to programmatically handle delivery errors. [#548, #559] -
Added
traceIdandspanIdto LogTape context in federation middleware so that log records emitted during request handling and queue processing include the OpenTelemetry trace and span IDs in their properties. This enables the@fedify/debuggerdashboard to display per-trace logs. [#561, #564] -
Fixed unbounded memory consumption when activity delivery fails with large error responses. The
SendActivityError.responseBodyproperty is now limited to 1 KiB to prevent memory pressure when remote servers return large HTML error pages (e.g., Cloudflare error pages of 50–100 KB each). This prevents potential OOM crashes in production environments with many unreachable inboxes. [#569]
@fedify/cli
- The Fedify CLI now runs natively on Node.js and Bun without requiring compiled binaries, providing a more natural JavaScript package experience for Node.js and Bun users. [#374, ...
Fedify 1.10.3
Released on February 1, 2026.
@fedify/fedify
- Fixed
traverseCollection()yielding no items when aCollectionhas an inlineCollectionPagein itsfirstproperty without an explicitid. This is common in Mastodon'srepliescollections. The function previously usedcollection.firstIdto determine pagination, which returnednullfor inline pages without anid, causing it to incorrectly fall into the non-paginated branch. [#550 by Lee Dogeon]
Fedify 1.9.5
Released on February 1, 2026.
@fedify/fedify
- Fixed
traverseCollection()yielding no items when aCollectionhas an inlineCollectionPagein itsfirstproperty without an explicitid. This is common in Mastodon'srepliescollections. The function previously usedcollection.firstIdto determine pagination, which returnednullfor inline pages without anid, causing it to incorrectly fall into the non-paginated branch. [#550 by Lee Dogeon]
Fedify 1.10.2
Released on January 23, 2026.
@fedify/testing
- Fixed
TestContext.getActorKeyPairs()returning empty array instead of calling registered key pairs dispatcher. The method now properly invokes the key pairs dispatcher when it is registered viasetKeyPairsDispatcher(). [#530]
Fedify 1.9.4
Released on January 23, 2026.
@fedify/testing
- Fixed
TestContext.getActorKeyPairs()returning empty array instead of calling registered key pairs dispatcher. The method now properly invokes the key pairs dispatcher when it is registered viasetKeyPairsDispatcher(). [#530]
Fedify 1.10.1
Released on January 22, 2026.
@fedify/testing
- Fixed
TestContext.getActor()andTestContext.getObject()returningnullinstead of calling registered dispatchers. The methods now properly invoke actor and object dispatchers when they are registered viasetActorDispatcher()andsetObjectDispatcher(). [#530]
Fedify 1.9.3
Released on January 22, 2026.
@fedify/testing
- Fixed
TestContext.getActor()andTestContext.getObject()returningnullinstead of calling registered dispatchers. The methods now properly invoke actor and object dispatchers when they are registered viasetActorDispatcher()andsetObjectDispatcher(). [#530]