Skip to content
AI Primer
release

Files SDK 1.9 adds Neon adapter, failover, and typed ValidationError

Files SDK 1.9 shipped a Neon adapter plus plugins for audit logging, caching, failover, signed URL policy, soft delete, tiering, and ZIP workflows. The release makes the storage API more production-ready for multi-backend uploads and safer presigned URL handling.

4 min read
Files SDK 1.9 adds Neon adapter, failover, and typed ValidationError
Files SDK 1.9 adds Neon adapter, failover, and typed ValidationError

TL;DR

You can jump straight to the Neon adapter docs, the failover plugin page, and the ZIP docs. The merged 1.9.0 release PR is also unusually useful here, because it spells out the release scope and dates instead of making you reconstruct the whole thing from the thread.

Neon adapter

The headline addition is a Neon adapter that keeps API parity with the package's other S3 style backends. According to haydenbleasel's Neon adapter post, it uses the AWS_* credentials Neon injects and keeps the same upload, download, delete, url(), and signedUploadUrl() surface.

The linked adapter docs add one implementation detail that matters if you actually wire it up: Neon uses path-style addressing, so the bucket travels in the request path instead of the hostname.

Audit, cache, and failover

Files SDK 1.9 gets a lot more opinionated about storage behavior under failure.

  • audit() awaits a structured record for each mutation, and haydenbleasel's audit post says successful writes can still fail closed if the audit sink rejects.
  • cache() targets cheap reads first, because haydenbleasel's cache post limits default caching to repeated head() and url() calls, while small download() caching stays opt in.
  • failover() only activates on backend outages, and haydenbleasel's failover post says real 404s and auth failures are returned as is instead of being masked by a secondary.

The official failover docs add the main caveat the tweet thread skipped: writes served by a secondary during an outage are not reconciled back to the primary automatically.

Signed URL policy and ValidationError

Two changes in 1.9 are really about deleting boring glue code from app layers.

  • signedUrlPolicy() turns safer defaults into a wrapper, and haydenbleasel's signedUrlPolicy post says it forces attachment downloads by default, caps URL lifetimes, and can enforce a maximum upload size on signedUploadUrl().
  • validation() now throws ValidationError, and haydenbleasel's ValidationError post says callers can branch on reason: "size" | "type" | "key" instead of parsing error strings.

The linked validation docs add one more useful detail: signed upload URL generation itself fails closed when size or type rules are configured, which shuts down an easy bypass path.

Soft delete, tiering, and ZIP

The back half of the release is a grab bag, but it is a practical one.

  • softDelete() moves deleted objects into a trash prefix, and haydenbleasel's softDelete post says you can list, restore, or purge those objects later.
  • tiering() splits one logical namespace across hot and cold adapters, while haydenbleasel's tiering post says reads, writes, copy, move, and merged listing all stay behind the same Files API.
  • zip() adds streaming archive creation, archive writes with zipTo(), and extraction with unzip(), and haydenbleasel's zip post says the implementation rejects zip-slip paths and has no native dependencies.

That last bit is the nicest surprise in the release. The ZIP docs say zip() streams lazily, but unzip() verifies CRC and size for extracted entries, which is a lot more serious than the usual "here's a helper for bundling files" feature.

Further reading

Discussion across the web

Where this story is being discussed, in original context.

On X· 4 threads
TL;DR3 posts
Neon adapter1 post
Audit, cache, and failover1 post
Soft delete, tiering, and ZIP1 post
Share on X