Skip to main content
Blog
Release noteAgent runtime / Express / Dependency migration

Foxl v0.2.21: Strands SDK 1.0 and Express 5

Upgraded to Strands SDK v1.0.0 stable with concurrent tool execution and cancellation hooks, plus Express 5 migration for async error handling and modern routing.

Foxl TeamUpdated 3 min read

The v0.2.21 runtime upgrade connecting Strands SDK 1.0 lifecycle events to an Express 5 application boundary.
On this page
Historical release note. Corrections and follow-up fixes are dated in the article. Last reviewed July 16, 2026.

Published on April 30, 2026, this post records the Strands Agent SDK and Express upgrades shipped in Foxl v0.2.21. The release changed agent-loop coordination and server route parsing without adding a new user-facing page.

Shipped behavior

  • @strands-agents/sdk moved from 1.0.0-rc.5 to stable 1.0.0.
  • Express moved from 4.18 to 5.2, with @types/express moving to version 5.
  • Express wildcard routes were migrated to named patterns such as *filename and *splat.
  • Per-invocation tool event callbacks moved from a shared map into the SDK's invocationState.

Concurrent tools

Strands 1.0 could execute multiple tool requests from one model turn concurrently. This reduced waiting when calls were independent. It did not prove that every model-generated batch was free of ordering dependencies, so side-effecting tools still needed their normal approval and execution safeguards.

Cancellation gates

Foxl registered BeforeInvocationEvent and BeforeModelCallEvent hooks. A stop request could prevent the next loop iteration or model request from starting. This improved stop behavior between calls, but did not promise immediate cancellation of work already running inside a provider or tool.

Implementation implication

Express 5 returns named wildcard captures as arrays. Workspace and webhook handlers therefore had to normalize a capture before treating it as a path:

const path = Array.isArray(param) ? param.join('/') : param;

Without that normalization, a nested path such as memory/daily/2026-04-30.md could not be reconstructed correctly. Express 5 also forwards rejected promises from async route handlers to error middleware, reducing the need for route-local rejection wrappers.

invocationState made the tool-event callback part of each agent.stream() call. That removed the global callback lookup and kept concurrent invocation state attached to the invocation that owned it.

Known limitation and follow-up

The focused Playwright file added with this release contained 11 cases for wildcard workspace routes, stop endpoint behavior, health, tools, providers, and models. It did not exercise a real in-flight provider cancellation, prove ordering safety for concurrent tools, or validate every route in the server.

Correction: May 11, 2026

The first v0.2.30 build reintroduced the rejected Express pattern :filename(*). Express 5 failed during startup before the embedded server could bind its port. The v0.2.30 rebuild restored *filename and *splat. This later regression does not change what v0.2.21 shipped, but it shows why the route syntax must remain covered.

Correction: July 15, 2026

Strands 1.0.0 is no longer current in this repository. Later recorded milestones included 1.1.0 on May 11, 1.7.0 on June 27, and 1.9.0 on July 15. Express remains on the 5.2 line.

How to verify

  • Start the local Foxl server and read and write both a root workspace file and a nested workspace path.
  • Call POST /api/chat/stop with and without a conversation id and confirm the success and validation paths.
  • Run npx playwright test tests/sdk-upgrade-e2e.spec.ts from foxl/apps/web while the local server is available.
  • Confirm foxl/package.json and the lockfile resolve the intended SDK and Express versions before attributing behavior to this historical release.

References and further reading

  1. Foxl tools and execution modelDocumentation
  2. Foxl release historyRelease