Skip to content

CBG-5715: fix fields documented as string that are not strings - #8654

Open
torcolvin wants to merge 3 commits into
CBG-5715-05-enum-descriptionsfrom
CBG-5715-06-string-type-fixes
Open

CBG-5715: fix fields documented as string that are not strings#8654
torcolvin wants to merge 3 commits into
CBG-5715-05-enum-descriptionsfrom
CBG-5715-06-string-type-fixes

Conversation

@torcolvin

@torcolvin torcolvin commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

CBG-5715

Split out of #8589 — stack 6/9, based on #8653.

Each of these is documented as string but is unmarshalled into a bool or an integer, so the documented request bodies would be rejected and the documented response types don't match what is emitted:

  • include_doc and offline query params are read with getBoolQuery (rest/admin_api.go:1632, rest/oidc_api.go:118)
  • _changes POST body (per readChangesOptionsFromJSON, rest/changes_api.go:599): limit is int, heartbeat/timeout are *uint64, active_only/include_docs are bool, and doc_ids is a real []string here — unlike the query parameter, which is a serialized string
  • event_handlers.max_processes is a uint (rest/config.go:218)
  • OIDC-token.expires_in is an int TTL (rest/oidc_api.go:67)
  • Compact-status.docs_purged, marked_attachments and purged_attachments are int64 counters

revocations is also dropped from the _changes POST body. Neither readChangesOptionsFromJSON nor updateChangesOptionsFromQuery reads it, so a POST cannot set it at all — not via the body and not via the query string. It is only honoured on GET (rest/changes_api.go:190). @bbrks spotted this on #8589 and suspected an oversight in the handler; removing the property documents current behaviour, and the handler gap is worth its own ticket if revocations should work on POST.

wait_for_process is left as a string: it really is parsed as a duration string, not a number (rest/config.go:219).

Covers the three @factory-droid comments on #8589 about the POST /_changes request bodies and OIDC-token.expires_in.

Pre-review checklist

  • Logging sensitive data? N/A — docs only
  • Updated relevant information in the API specifications in docs/api

🤖 Generated with Claude Code

@factory-droid

factory-droid Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Droid finished @torcolvin's task —— View job


The schema-type fixes look consistent with the Go implementation. The remaining gap is that POST /_changes request-body schemas still omit supported options (since in both admin and public, and version_type in public), which can mislead users and break generated clients.

Comment thread docs/api/paths/admin/keyspace-_changes.yaml
Comment thread docs/api/paths/public/keyspace-_changes.yaml
@torcolvin
torcolvin requested review from a team and a lite review from Copilot August 23, 2026 18:32
@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown

Redocly previews

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the OpenAPI specifications under docs/api/ to align documented request/response types with how Sync Gateway actually parses and emits values (primarily correcting fields previously documented as string that are in practice booleans or integers).

Changes:

  • Fix _changes POST body schema types (e.g., limit, since, active_only, doc_ids, heartbeat, timeout) and adjust documented fields to match handler behavior.
  • Correct component schema field types for OIDC token responses, event handler configuration, and compaction status counters.
  • Update shared query-parameter component schemas (include_doc, offline) from string to boolean.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
docs/api/paths/public/keyspace-_changes.yaml Updates the public _changes endpoint schema (notably POST body field types and added fields).
docs/api/paths/admin/keyspace-_changes.yaml Updates the admin _changes endpoint POST body schema field types to match server parsing.
docs/api/components/schemas.yaml Fixes component schema field types (OIDC token TTL, event handler concurrency, compaction status counters).
docs/api/components/parameters.yaml Corrects shared query parameter schemas to boolean where handlers parse booleans.
Suppressed comments (4)

docs/api/components/schemas.yaml:2180

  • marked_attachments is emitted as an int64 counter (see db/background_mgr_attachment_compaction.go), so the schema should use format: int64 (and it’s a count, so it should be non-negative).
      type: integer

docs/api/components/schemas.yaml:2186

  • purged_attachments is emitted as an int64 counter (see db/background_mgr_attachment_compaction.go), so the schema should use format: int64 (and it’s a count, so it should be non-negative).
      type: integer

docs/api/paths/public/keyspace-_changes.yaml:182

  • timeout in the POST body is clamped/validated server-side (default 300000ms, max 900000ms). Adding these constraints to the schema helps prevent documented request bodies that the server will reject.
              type: integer

docs/api/paths/admin/keyspace-_changes.yaml:195

  • timeout in the POST body is clamped/validated server-side (default 300000ms, max 900000ms). Adding these constraints to the schema helps prevent documented request bodies that the server will reject.
              type: integer

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/api/components/schemas.yaml
Comment thread docs/api/components/schemas.yaml
Comment thread docs/api/components/schemas.yaml
Comment thread docs/api/paths/public/keyspace-_changes.yaml
Comment thread docs/api/paths/admin/keyspace-_changes.yaml
torcolvin added a commit that referenced this pull request Aug 23, 2026
docs_purged is int64 (db/background_mgr_tombstone_compaction.go:83) and
marked_attachments/purged_attachments are int64
(db/background_mgr_attachment_compaction.go:323-324).  An unformatted
type: integer codegens as int32 for many generators, so add format:
int64.  All three are monotonic counters, hence minimum: 0.

Also fixes "even queue" -> "event queue" in the wait_for_process
description.  Both raised by Copilot on #8654.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
torcolvin added a commit that referenced this pull request Aug 23, 2026
max_processes is a uint, and db/event_manager.go:69-70 maps 0 to
kMaxActiveEvents (500), so document minimum: 0 with the effective
default and say what 0 means.  Raised by Copilot on #8654.

heartbeat and timeout in the _changes POST bodies now carry the same
defaults and bounds already documented on the GET query parameters:
heartbeat defaults to 0 and, when non-zero, is clamped up to
kMinHeartbeatMS (25000); timeout defaults to kDefaultTimeoutMS (300000)
and is capped at kMaxTimeoutMS (900000).  See GetRestrictedInt, which
readChangesOptionsFromJSON calls with allowZero=true.  Copilot flagged
these as heartbeat-only, but the timeout default is 300000, not 0.

Also drops the revs_limit allow_conflicts note.  Both branches it
describes exist (db/database.go:504-508, rest/config.go:936-940) but
neither is reachable from config: allow_conflicts=true is rejected in
the same validateVersion (rest/config.go:1149-1150) and
DefaultAllowConflicts is false, so only the test-only
EnableAllowConflicts gets there.  Raised by @factory-droid on #8656.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@torcolvin
torcolvin requested a review from bbrks August 23, 2026 18:51
torcolvin added a commit that referenced this pull request Aug 24, 2026
docs_purged is int64 (db/background_mgr_tombstone_compaction.go:83) and
marked_attachments/purged_attachments are int64
(db/background_mgr_attachment_compaction.go:323-324).  An unformatted
type: integer codegens as int32 for many generators, so add format:
int64.  All three are monotonic counters, hence minimum: 0.

Also fixes "even queue" -> "event queue" in the wait_for_process
description.  Both raised by Copilot on #8654.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@torcolvin
torcolvin force-pushed the CBG-5715-06-string-type-fixes branch from 702c1b8 to 2ca7587 Compare August 24, 2026 17:31
torcolvin added a commit that referenced this pull request Aug 24, 2026
max_processes is a uint, and db/event_manager.go:69-70 maps 0 to
kMaxActiveEvents (500), so document minimum: 0 with the effective
default and say what 0 means.  Raised by Copilot on #8654.

heartbeat and timeout in the _changes POST bodies now carry the same
defaults and bounds already documented on the GET query parameters:
heartbeat defaults to 0 and, when non-zero, is clamped up to
kMinHeartbeatMS (25000); timeout defaults to kDefaultTimeoutMS (300000)
and is capped at kMaxTimeoutMS (900000).  See GetRestrictedInt, which
readChangesOptionsFromJSON calls with allowZero=true.  Copilot flagged
these as heartbeat-only, but the timeout default is 300000, not 0.

Also drops the revs_limit allow_conflicts note.  Both branches it
describes exist (db/database.go:504-508, rest/config.go:936-940) but
neither is reachable from config: allow_conflicts=true is rejected in
the same validateVersion (rest/config.go:1149-1150) and
DefaultAllowConflicts is false, so only the test-only
EnableAllowConflicts gets there.  Raised by @factory-droid on #8656.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
torcolvin and others added 3 commits August 24, 2026 13:49
Each of these is documented as `string` but is unmarshalled into a bool or
an integer, so the documented request bodies would be rejected and the
documented response types don't match what is emitted:

- `include_doc` and `offline` query params are read with `getBoolQuery`
- `_changes` POST body (per `readChangesOptionsFromJSON`): `limit`,
  `heartbeat` and `timeout` are numbers, `active_only` and `include_docs`
  are bools, and `doc_ids` is a real JSON array here (unlike the query
  parameter, which is a serialized string)
- `event_handlers.max_processes` is a `uint`
- `OIDC-token.expires_in` is an `int` TTL
- `Compact-status.docs_purged`, `marked_attachments` and
  `purged_attachments` are `int64` counters

`revocations` is also dropped from the `_changes` POST body. Neither
`readChangesOptionsFromJSON` nor `updateChangesOptionsFromQuery` reads it,
so a POST cannot set it at all — not via the body and not via the query
string. It is only honoured on GET.

`wait_for_process` is left as a string: it really is parsed as a duration
string, not a number.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
readChangesOptionsFromJSON parses since, request_plus and version_type
from the POST body, and handleChanges is registered once for GET/HEAD/
POST on both the public and admin routers, so there is no port-based
difference in what the body accepts.  The specs had drifted anyway:

- admin POST body was missing since
- public POST body was missing since, request_plus and version_type
- public GET was missing the request_plus query parameter

since is typed oneOf string/integer in the body because it is read as a
json.RawMessage and run through base.ConvertJSONString, so both "3::2"
and a bare 3 parse.  As a query parameter it stays a string.

accept_encoding is deliberately left undocumented: the POST path
discards the compress return value, so it only has an effect on the
WebSocket feed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
docs_purged is int64 (db/background_mgr_tombstone_compaction.go:83) and
marked_attachments/purged_attachments are int64
(db/background_mgr_attachment_compaction.go:323-324).  An unformatted
type: integer codegens as int32 for many generators, so add format:
int64.  All three are monotonic counters, hence minimum: 0.

Also fixes "even queue" -> "event queue" in the wait_for_process
description.  Both raised by Copilot on #8654.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@torcolvin
torcolvin force-pushed the CBG-5715-06-string-type-fixes branch from 2ca7587 to a6eca9c Compare August 24, 2026 17:51
torcolvin added a commit that referenced this pull request Aug 24, 2026
max_processes is a uint, and db/event_manager.go:69-70 maps 0 to
kMaxActiveEvents (500), so document minimum: 0 with the effective
default and say what 0 means.  Raised by Copilot on #8654.

heartbeat and timeout in the _changes POST bodies now carry the same
defaults and bounds already documented on the GET query parameters:
heartbeat defaults to 0 and, when non-zero, is clamped up to
kMinHeartbeatMS (25000); timeout defaults to kDefaultTimeoutMS (300000)
and is capped at kMaxTimeoutMS (900000).  See GetRestrictedInt, which
readChangesOptionsFromJSON calls with allowZero=true.  Copilot flagged
these as heartbeat-only, but the timeout default is 300000, not 0.

Also drops the revs_limit allow_conflicts note.  Both branches it
describes exist (db/database.go:504-508, rest/config.go:936-940) but
neither is reachable from config: allow_conflicts=true is rejected in
the same validateVersion (rest/config.go:1149-1150) and
DefaultAllowConflicts is false, so only the test-only
EnableAllowConflicts gets there.  Raised by @factory-droid on #8656.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
torcolvin added a commit that referenced this pull request Aug 24, 2026
max_processes is a uint, and db/event_manager.go:69-70 maps 0 to
kMaxActiveEvents (500), so document minimum: 0 with the effective
default and say what 0 means.  Raised by Copilot on #8654.

heartbeat and timeout in the _changes POST bodies now carry the same
defaults and bounds already documented on the GET query parameters:
heartbeat defaults to 0 and, when non-zero, is clamped up to
kMinHeartbeatMS (25000); timeout defaults to kDefaultTimeoutMS (300000)
and is capped at kMaxTimeoutMS (900000).  See GetRestrictedInt, which
readChangesOptionsFromJSON calls with allowZero=true.  Copilot flagged
these as heartbeat-only, but the timeout default is 300000, not 0.

Also drops the revs_limit allow_conflicts note.  Both branches it
describes exist (db/database.go:504-508, rest/config.go:936-940) but
neither is reachable from config: allow_conflicts=true is rejected in
the same validateVersion (rest/config.go:1149-1150) and
DefaultAllowConflicts is false, so only the test-only
EnableAllowConflicts gets there.  Raised by @factory-droid on #8656.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bbrks bbrks removed their assignment Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants