DocsAWS 101Blog
← Back to Blog

v1.3.28 — ECS Task Metadata V4 and DynamoDB legacy params

May 5, 2026 · v1.3.28

One new endpoint family and a DynamoDB parity fix that's been hiding for a while.

1. ECS Task Metadata V4

Every container started by RunTask now gets ECS_CONTAINER_METADATA_URI_V4 injected into its environment. The MiniStack gateway serves the standard task-metadata routes off the existing 4566 port, keyed by a per-container secrets.token_urlsafe(32) value:

Standard com.amazonaws.ecs.* labels are stamped on the Docker container (task-arn, container-name, task-definition-family, task-definition-version, cluster) so anything that scrapes labels works the same way it does on real ECS. The token registry is volatile by design: it's stripped from persisted state and cleared by /_ministack/reset.

Unlocks running ECS instrumentation, security agents, and any application code that calls $ECS_CONTAINER_METADATA_URI_V4/task end-to-end against MiniStack — including in CI. Contributed by @YakirOren.

Same PR also extends RunTask to translate more of the task definition into Docker run options:

$ aws --endpoint-url=http://localhost:4566 ecs run-task \
    --cluster default --task-definition my-app
# inside the container:
$ wget -qO- "$ECS_CONTAINER_METADATA_URI_V4/task" | jq .Containers

2. DynamoDB legacy Expected and KeyConditions

The pre-expression DynamoDB API (Expected on PutItem / UpdateItem / DeleteItem, KeyConditions on Query, full ScanFilter / QueryFilter operator coverage) was previously ignored — only the modern expression form was honoured. SDKs and code paths still using the legacy parameters (older Boto2 ports, some Java SDK v1 callers, Terraform code paths that round-trip through legacy schemas, and AWS CLI scripts written before the expression API existed) silently passed conditions that should have failed, or vice-versa.

Fixed in this release. Every ComparisonOperator the legacy API supports now evaluates correctly with type-aware comparison (so numeric {"N":"10"} > {"N":"2"} is true, not the lexicographic "10" < "2" a string compare would give):

EQ, NE, LE, LT, GE, GT, NOT_NULL, NULL, CONTAINS, NOT_CONTAINS, BEGINS_WITH, IN, BETWEEN.

Mixing the legacy and expression forms in the same call now returns the AWS-shape ValidationException ("Can not use both expression and non-expression parameters in the same request") instead of silently honouring one and dropping the other. Expected shorthand forms ({"Exists": true/false}, {"Value": <attr>}) and ConditionalOperator: "OR" are honoured.

3. TransactWriteItems multi-failure reporting

When a TransactWriteItems call had multiple items whose conditions failed, only the first failure was marked in CancellationReasons; every subsequent item was returned as Code: "None". AWS returns a ConditionalCheckFailed entry for every failing item in the transaction. MiniStack now evaluates all conditions in a first pass, then emits the cancellation array in one go — matching the AWS shape exactly. ReturnValuesOnConditionCheckFailure="ALL_OLD" still attaches the prior Item per failing reason where the per-op flag was set.

Upgrade

docker pull ministackorg/ministack:1.3.28
docker run -d -p 4566:4566 ministackorg/ministack:1.3.28

Or pin in compose.yaml:

services:
  ministack:
    image: ministackorg/ministack:1.3.28
    ports:
      - "4566:4566"

Ship together

Shipped by the MiniStack community. Contributions credited throughout. GitHub · r/ministack