fix(datastore): revert strict schema validation for s3 and gcs #269

Merged
stack72 merged 1 commit from fix/revert-strict-datastores into main 2026-09-10 16:56:31 +00:00
Owner

Summary

  • Revert .strict() on S3 and GCS datastore configSchema definitions added in #268
  • Remove the configSchema rejects unknown keys tests from both datastores
  • Bump manifest versions to 2026.09.10.1 for both extensions

The swamp runtime passes namespace (and potentially other keys) through the config object to datastore extensions. .strict() rejects these as "Unrecognized key", breaking all namespace-related UAT tests:

Error: Invalid config for "@swamp/s3-datastore": [
  { "code": "unrecognized_keys", "keys": ["namespace"], "message": "Unrecognized key: \"namespace\"" }
]

Vault extensions keep .strict() since the runtime does not inject extra keys into vault configs.

Test plan

  • deno check, deno lint, deno fmt --check pass for both s3 and gcs
  • GCS unit tests pass (15/15)
  • S3 unit tests pass (requires Docker for mock S3)
  • CI matrix covers both extensions
  • UAT re-run succeeds after publish

🤖 Generated with Claude Code

## Summary - Revert `.strict()` on S3 and GCS datastore `configSchema` definitions added in #268 - Remove the `configSchema rejects unknown keys` tests from both datastores - Bump manifest versions to `2026.09.10.1` for both extensions The swamp runtime passes `namespace` (and potentially other keys) through the config object to datastore extensions. `.strict()` rejects these as `"Unrecognized key"`, breaking all namespace-related UAT tests: ``` Error: Invalid config for "@swamp/s3-datastore": [ { "code": "unrecognized_keys", "keys": ["namespace"], "message": "Unrecognized key: \"namespace\"" } ] ``` Vault extensions keep `.strict()` since the runtime does not inject extra keys into vault configs. ## Test plan - [x] `deno check`, `deno lint`, `deno fmt --check` pass for both s3 and gcs - [x] GCS unit tests pass (15/15) - [ ] S3 unit tests pass (requires Docker for mock S3) - [ ] CI matrix covers both extensions - [ ] UAT re-run succeeds after publish 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(datastore): revert strict schema validation for s3 and gcs datastores
All checks were successful
CI: Datastores / datastore/gcs - check (pull_request) Successful in 32s
CI: Datastores / datastore/gcs - fmt (pull_request) Successful in 31s
CI: Datastores / datastore/gcs - lint (pull_request) Successful in 26s
CI: Datastores / datastore/s3 - check (pull_request) Successful in 32s
CI: Datastores / datastore/s3 - fmt (pull_request) Successful in 26s
CI: Datastores / datastore/gcs - test (pull_request) Successful in 50s
CI: Datastores / datastore/s3 - lint (pull_request) Successful in 35s
CI: Datastores / datastore/gcs - lockfile up to date (pull_request) Successful in 34s
CI: Reviews / Detect Changes (pull_request) Successful in 25s
CI: Reviews / CI Security Review (pull_request) Has been skipped
CI: Datastores / datastore/s3 - lockfile up to date (pull_request) Successful in 29s
CI: Datastores / datastore/s3 - test (pull_request) Successful in 1m30s
CI / Actions Audit (pull_request) Successful in 37s
CI: Reviews / Claude Code Review (pull_request) Successful in 1m46s
CI: Datastores / Gate: Datastores (pull_request) Successful in 1s
CI / Dependency Audit (pull_request) Successful in 2m39s
CI / Gate: Audit (pull_request) Successful in 0s
CI: Reviews / Adversarial Code Review (pull_request) Successful in 2m26s
CI: Reviews / Gate: Reviews (pull_request) Successful in 0s
933a3a0915
The swamp runtime passes extra keys like `namespace` through the config
object to datastore extensions. `.strict()` rejects these as unrecognized
keys, breaking all namespace-related UAT tests. Datastores need to accept
unknown keys since the runtime injects them before the extension strips
them during parse.

Keeps `.strict()` on vault extensions where the runtime does not inject
extra keys.

Fixes swamp-club/swamp-uat#34490362437

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Author
Owner

Code Review

This PR reverts the .strict() Zod schema validation added in #268 for both the S3 and GCS datastore extensions, and bumps each manifest version from 2026.09.10.0 to 2026.09.10.1.

Blocking Issues

None.

Suggestions

  1. Silent unknown-key stripping may hide misconfiguration. Without .strict(), Zod's default mode strips unrecognized config keys rather than rejecting them. A user who typos a config key (e.g., endpiont instead of endpoint, or forcePathStyle spelled differently) will receive no error — the key is silently dropped and the default behaviour applies. This was the trade-off intentionally reverted, but it is worth documenting in the schema description or a code comment so future authors understand why .strict() was deliberately omitted.

  2. Consistency opportunity (non-blocking). The GCS test that was removed used credentials_file as the unknown key. That field name suggests there may be user confusion about how to supply GCS credentials to this extension. If that is a common misconfiguration, a z.never() or a targeted .refine() with a helpful error message for that specific key could be added to guide users — but this is optional and outside the scope of this revert.

## Code Review This PR reverts the `.strict()` Zod schema validation added in #268 for both the S3 and GCS datastore extensions, and bumps each manifest version from `2026.09.10.0` to `2026.09.10.1`. ### Blocking Issues None. ### Suggestions 1. **Silent unknown-key stripping may hide misconfiguration.** Without `.strict()`, Zod's default mode strips unrecognized config keys rather than rejecting them. A user who typos a config key (e.g., `endpiont` instead of `endpoint`, or `forcePathStyle` spelled differently) will receive no error — the key is silently dropped and the default behaviour applies. This was the trade-off intentionally reverted, but it is worth documenting in the schema description or a code comment so future authors understand why `.strict()` was deliberately omitted. 2. **Consistency opportunity (non-blocking).** The GCS test that was removed used `credentials_file` as the unknown key. That field name suggests there may be user confusion about how to supply GCS credentials to this extension. If that is a common misconfiguration, a `z.never()` or a targeted `.refine()` with a helpful error message for that specific key could be added to guide users — but this is optional and outside the scope of this revert.
Author
Owner

Adversarial Review

PR summary: Removes .strict() from the zod config schemas in both S3 and GCS datastore extensions, reverting the strict validation added in f69c46c73. Removes the corresponding "rejects unknown keys" tests. Bumps manifest versions to 2026.09.10.1.

Medium

  1. Silent config typos go undetected (datastore/s3/extensions/datastores/s3.ts:103, datastore/gcs/extensions/datastores/gcs.ts:111)

    Without .strict(), zod's default behavior strips unrecognized keys silently. A typo like { bucket: "prod-bucket", endpont: "http://localhost:4443" } (note endpont) will parse successfully — the misspelled key is silently dropped, and the extension connects to the real AWS/GCS API instead of the intended local emulator. Same applies to forcePathStlye, reigon, pullConcurency, etc.

    This was presumably the exact scenario that motivated adding .strict() in f69c46c73, and the revert presumably has its own justification (e.g., forward compatibility or integration pain). Noting it as medium because this is a deliberate design tradeoff, not an oversight — but the misconfiguration-to-wrong-cloud-endpoint failure mode is worth keeping in mind.

Low

  1. No config-level feedback mechanism to replace strict validation (datastore/s3/extensions/datastores/s3.ts:103, datastore/gcs/extensions/datastores/gcs.ts:111)

    If strict validation was removed because it broke existing deployments with extra keys (e.g., keys consumed by a wrapper layer), a middle ground like .passthrough() with a warning log for unrecognized keys would catch typos without breaking compatibility. This is a design suggestion, not a bug.

Verdict

PASS — The changes are minimal, correct, and internally consistent. The .strict() removal, test cleanup, and version bumps are all properly coordinated. No logic errors, no security vulnerabilities, no resource management issues. The silent-typo tradeoff is a known consequence of the design choice, not a defect.

## Adversarial Review **PR summary:** Removes `.strict()` from the zod config schemas in both S3 and GCS datastore extensions, reverting the strict validation added in f69c46c73. Removes the corresponding "rejects unknown keys" tests. Bumps manifest versions to `2026.09.10.1`. ### Medium 1. **Silent config typos go undetected** (`datastore/s3/extensions/datastores/s3.ts:103`, `datastore/gcs/extensions/datastores/gcs.ts:111`) Without `.strict()`, zod's default behavior strips unrecognized keys silently. A typo like `{ bucket: "prod-bucket", endpont: "http://localhost:4443" }` (note `endpont`) will parse successfully — the misspelled key is silently dropped, and the extension connects to the real AWS/GCS API instead of the intended local emulator. Same applies to `forcePathStlye`, `reigon`, `pullConcurency`, etc. This was presumably the exact scenario that motivated adding `.strict()` in f69c46c73, and the revert presumably has its own justification (e.g., forward compatibility or integration pain). Noting it as medium because this is a deliberate design tradeoff, not an oversight — but the misconfiguration-to-wrong-cloud-endpoint failure mode is worth keeping in mind. ### Low 1. **No config-level feedback mechanism to replace strict validation** (`datastore/s3/extensions/datastores/s3.ts:103`, `datastore/gcs/extensions/datastores/gcs.ts:111`) If strict validation was removed because it broke existing deployments with extra keys (e.g., keys consumed by a wrapper layer), a middle ground like `.passthrough()` with a warning log for unrecognized keys would catch typos without breaking compatibility. This is a design suggestion, not a bug. ### Verdict **PASS** — The changes are minimal, correct, and internally consistent. The `.strict()` removal, test cleanup, and version bumps are all properly coordinated. No logic errors, no security vulnerabilities, no resource management issues. The silent-typo tradeoff is a known consequence of the design choice, not a defect.
stack72 deleted branch fix/revert-strict-datastores 2026-09-10 16:56:32 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
swamp-club/swamp-extensions!269
No description provided.