DocsAWS 101Blog
← Back to Blog

v1.3.16 — Warm-boot persistence sweep, wire-format fixes, and a :full image for Athena

April 27, 2026 · v1.3.16

1.3.16 is a hardening release. Twelve account-scoped state dicts that were silently disappearing on warm-boot are now persisted, ten list endpoints stop returning NextToken: null (which Java and Go pagination clients would loop on), CloudFormation Lambdas backed by S3 finally execute their actual code instead of returning a mock response, and there's a new :full Docker tag with DuckDB, PostgreSQL, and MySQL drivers in one image.

1. ministackorg/ministack:full — DuckDB-backed Athena, no source builds

The default image is Alpine-based, which keeps it small (~110 MB) but also keeps it free of manylinux-only wheels. DuckDB and psycopg2-binary ship manylinux but not musllinux; on Alpine they fall back to slow source builds or silently disable themselves. Athena's DuckDB engine has been hitting that pain since the engine landed.

1.3.16 publishes a Debian/glibc variant alongside the regular image:

docker pull ministackorg/ministack:full

It's a strict superset of the regular image — same SFTP support, same env-var contract, same healthcheck — plus duckdb, psycopg2-binary, and pymysql. The :full tag tracks the latest release; pinned variants are also published as :1.3.16-full and :1.3-full. The regular :latest and :1.3.16 tags are unchanged.

The full image self-identifies via /_ministack/health:

{ "edition": "full", "version": "1.3.16", "services": { ... } }

2. Twelve state dicts that were silently dropped on warm-boot

PERSIST_STATE=1 is the knob that makes MiniStack survive a container restart. The contract is simple: every service module exposes get_state() and restore_state(), and the persistence layer round-trips them through JSON.

The contract was incomplete. Twelve module-level AccountScopedDicts were being mutated by public APIs but missing from one or both halves of the persistence path. Most landed in 1.3.16:

There was also a subtler bug in SQS _queue_name_to_url: the dict was snapshotted via dict(asd) instead of copy.deepcopy(asd). AccountScopedDict.__iter__ only yields the current request's keys, so multi-tenant deployments lost every other tenant's queue-name mappings on shutdown serialisation.

Big thanks to @bognari for pushing through most of this audit.

3. Wire-format alignment with the JVM and Go SDKs

A class of bugs easy to miss in Python-only testing: AWS SDKs differ in how they handle null and PascalCase. boto3 strips nulls client-side and is forgiving about case; Java SDK v2 and Go SDK v2 are stricter.

4. CloudFormation Lambdas backed by S3 — completely broken before

A quiet showstopper for CDK users. The CloudFormation provisioner for AWS::Lambda::Function accepted Code.S3Bucket / Code.S3Key and stored them as metadata on the function record — but never actually fetched the bytes. Every CFN-deployed Lambda backed by S3 had code_zip = None and returned a hardcoded "Mock response - no code deployed" on invocation. Inline ZipFile was unaffected; the S3 path simply never worked.

1.3.16 fixes the provisioner to actually call the Lambda S3 helper. While we were there, Code.S3ObjectVersion is now threaded end-to-end (CreateFunction, UpdateFunctionCode, PublishLayerVersion, and the CFN provisioner) — so Terraform aws_lambda_function.s3_object_version and CDK Code.fromBucket(..., objectVersion=...) deploy the pinned bytes instead of silently picking up the latest.

resource "aws_s3_object" "lambda_zip" {
  bucket = aws_s3_bucket.deploy.id
  key    = "fn.zip"
  source = "build/fn.zip"
  etag   = filemd5("build/fn.zip")
}

resource "aws_lambda_function" "fn" {
  function_name     = "my-fn"
  role              = aws_iam_role.fn.arn
  handler           = "index.handler"
  runtime           = "python3.12"
  s3_bucket         = aws_s3_object.lambda_zip.bucket
  s3_key            = aws_s3_object.lambda_zip.key
  s3_object_version = aws_s3_object.lambda_zip.version_id
}

Also in this release

Upgrade

# Regular image (Alpine, ~110 MB)
docker pull ministackorg/ministack:1.3.16

# Full image (Debian + DuckDB + psycopg2 + pymysql, ~360 MB)
docker pull ministackorg/ministack:1.3.16-full

# pip
pip install -U ministack

Full changelog: CHANGELOG.md.

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