fix: AgentParamsSchema must accept paperclip property in wake payload#72565
fix: AgentParamsSchema must accept paperclip property in wake payload#72565bryangauvin wants to merge 1 commit into
Conversation
Greptile SummaryAdds Confidence Score: 5/5This PR is safe to merge — the change is minimal, consistent with existing Type.Unknown() usage (e.g. attachments), and well-tested. Single-field optional addition to a schema, with no logic changes. The approach mirrors the existing attachments: Type.Optional(Type.Array(Type.Unknown())) pattern. All six new tests are well-targeted and cover the critical rejection paths. No files require special attention. Reviews (1): Last reviewed commit: "fix: AgentParamsSchema must accept paper..." | Re-trigger Greptile |
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Close as duplicate/superseded. Current main still has the reported Paperclip So I’m closing this here and keeping the remaining discussion on the canonical linked item. Review detailsBest possible solution: Close this duplicate PR, keep #62102 and one selected implementation branch as the canonical path, and carry over any useful validator coverage while landing a single additive Gateway protocol fix with generated artifacts, tests, docs/changelog as needed, and duplicate cleanup after merge. Do we have a high-confidence way to reproduce the issue? Yes. A valid Gateway Is this the best way to solve the issue? No as a standalone merge target. The schema addition likely unblocks the reported payload, but this PR duplicates active Paperclip fix branches and omits required protocol generated-artifact follow-through; the maintainable path is one canonical branch with the chosen protocol shape. Security review: Security review cleared: The diff only changes a TypeBox protocol schema and Vitest tests; it does not touch dependencies, workflows, lockfiles, install/build/release scripts, publishing metadata, downloaded artifacts, or secret handling. What I checked:
Likely related people:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 359d871293e8. |
…tadata The first commit on this branch added `paperclip: Type.Optional(Type.Unknown())` to AgentParamsSchema as a vendor-named root-level tolerance field. The review on openclaw#74974 (and the surrounding history of openclaw#62102, openclaw#74635, openclaw#72565, openclaw#69139, openclaw#75901 — three earlier PRs proposing the same vendor-named shape, all closed without merge) makes the underlying request clear: the right contract is a generic opaque-metadata namespace any external agent or plugin adapter can write under, not a name-per-vendor field that grows the gateway protocol surface every time a new adapter ships. This commit lands that namespace alongside the existing alias: - AgentParamsSchema gains `adapterMeta: Type.Optional(Type.Record( Type.String(), Type.Unknown()))`. Each adapter writes its own top-level key under it (`adapterMeta: { paperclip: {...}, greptile: {...} }`); the gateway accepts the bag as opaque and never inspects it. - The existing `paperclip: Type.Optional(Type.Unknown())` field is kept as a backward-compatibility alias, with a comment documenting that new adapter metadata should use `adapterMeta` and that this field can be removed once the published Paperclip adapter cuts a release that nests its payload under `adapterMeta.paperclip`. Heartbeats from current Paperclip releases keep dispatching during the transition. - `additionalProperties: false` on AgentParamsSchema is left intact, so a typo'd root field (e.g. `idempotnecyKey`) still fails validation before dispatch — the fix doesn't widen the schema, it just adds two named landing pads. Tests in src/gateway/protocol/agent-params-validator.test.ts now cover: - adapterMeta with multiple adapter keys (paperclip + greptile) accepted - empty adapterMeta and adapterMeta with primitive values accepted - both surfaces side by side (paperclip + adapterMeta.paperclip) accepted - adapterMeta with a non-object value rejected - existing paperclip-only path unchanged - truly unknown root properties still rejected - canonical message + idempotencyKey still required Swift bindings in apps/shared/OpenClawKit/Sources/OpenClawProtocol/ GatewayModels.swift mirror the new field as `adaptermeta: [String: AnyCodable]?` in the four codegen sites (declaration, init signature, init body, CodingKeys = "adapterMeta"), matching the pattern used for `inputprovenance` and the existing `paperclip` mirror. CHANGELOG.md gets a `Gateway/protocol:` entry under `## Unreleased` describing the namespace + alias and citing openclaw#74635 and openclaw#62102 as the issues being closed. Refs openclaw#74974, openclaw#74635, openclaw#62102
… alias on AgentParamsSchema
Paperclip and other external agents inject a root-level metadata blob
when invoking agents via the openclaw_gateway adapter, but
AgentParamsSchema is declared with additionalProperties: false so the
gateway rejects the entire payload before dispatch:
invalid agent params: at root: unexpected property 'paperclip'
Reported by openclaw#74635 (Paperclip rev 3494e84 vs OpenClaw 2026.4.26
be8c246) and openclaw#62102. Three earlier PRs proposed a vendor-named root
field (openclaw#69139, openclaw#72565, openclaw#75901) - all closed without merge - so this
lands the fix as a generic namespace plus a backward-compatibility
alias instead.
Schema (src/gateway/protocol/schema/agent.ts)
- AgentParamsSchema gains 'adapterMeta: Type.Optional(Type.Record(
Type.String(), Type.Unknown()))'. Each external agent or plugin
adapter writes under its own top-level key here
(adapterMeta: { paperclip: {...}, greptile: {...} }); the gateway
accepts the bag as-is and never inspects it. New adapters can land
protocol-side without growing the schema.
- AgentParamsSchema also gains 'paperclip: Type.Optional(Type.Unknown())'
as a backward-compatibility alias, with a comment marking it for
removal once the published Paperclip adapter cuts a release that
nests under adapterMeta.paperclip. Heartbeats from current Paperclip
releases keep dispatching during the transition.
- additionalProperties: false on AgentParamsSchema is intentionally
untouched. Truly unknown root fields (e.g. typo'd 'idempotnecyKey')
still fail validation before dispatch.
Swift bindings (apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift)
Mirror the two new fields on the AgentParams struct in all four
codegen positions (declaration, init signature, init body, CodingKeys),
following the existing 'inputprovenance' and 'cleanupbundlemcponrunend'
pattern:
public let adaptermeta: [String: AnyCodable]?
public let paperclip: AnyCodable?
The macOS-side mirror was deleted upstream so only the shared one needs
to be regenerated.
Tests (src/gateway/protocol/agent-params-validator.test.ts, new)
- minimal canonical payload accepted, missing message/idempotencyKey rejected
- root-level paperclip alias accepts object, string, number, boolean, null
- adapterMeta with one or more adapter keys accepted
- empty adapterMeta and adapterMeta with primitive entry values accepted
- both surfaces side by side (paperclip + adapterMeta.paperclip) accepted
- adapterMeta with non-object value rejected (string, number, boolean, null, array)
- truly unknown root properties still rejected (additionalProperties guard intact)
Verification
- pnpm exec oxfmt --check --threads=1 on the touched .ts files: clean.
- Standalone tsx reproducer importing the schema body and compiling it
with the same Ajv configuration as src/gateway/protocol/index.ts:
19/19 cases pass (covering the 8 PR test scenarios above plus their
primitive variants).
- pnpm test src/gateway/protocol/agent-params-validator.test.ts is
expected to pass on CI; local run was blocked by registry access
while preparing the github-pinned @openclaw/fs-safe workspace dep.
Changelog
Added one bullet under ## Unreleased -> ### Changes describing the
namespace + alias and citing openclaw#74635 and openclaw#62102.
Fixes openclaw#74635.
Fixes openclaw#62102.
Refs openclaw#69139, openclaw#72565, openclaw#75901.
… alias on AgentParamsSchema
Paperclip and other external agents inject a root-level metadata blob
when invoking agents via the openclaw_gateway adapter, but
AgentParamsSchema is declared with additionalProperties: false so the
gateway rejects the entire payload before dispatch:
invalid agent params: at root: unexpected property 'paperclip'
Reported by openclaw#74635 (Paperclip rev 3494e84 vs OpenClaw 2026.4.26
be8c246) and openclaw#62102. Three earlier PRs proposed a vendor-named root
field (openclaw#69139, openclaw#72565, openclaw#75901) - all closed without merge - so this
lands the fix as a generic namespace plus a backward-compatibility
alias instead.
Schema (src/gateway/protocol/schema/agent.ts)
- AgentParamsSchema gains 'adapterMeta: Type.Optional(Type.Record(
Type.String(), Type.Unknown()))'. Each external agent or plugin
adapter writes under its own top-level key here
(adapterMeta: { paperclip: {...}, greptile: {...} }); the gateway
accepts the bag as-is and never inspects it. New adapters can land
protocol-side without growing the schema.
- AgentParamsSchema also gains 'paperclip: Type.Optional(Type.Unknown())'
as a backward-compatibility alias, with a comment marking it for
removal once the published Paperclip adapter cuts a release that
nests under adapterMeta.paperclip. Heartbeats from current Paperclip
releases keep dispatching during the transition.
- additionalProperties: false on AgentParamsSchema is intentionally
untouched. Truly unknown root fields (e.g. typo'd 'idempotnecyKey')
still fail validation before dispatch.
Swift bindings (apps/shared/OpenClawKit/Sources/OpenClawProtocol/GatewayModels.swift)
Mirror the two new fields on the AgentParams struct in all four
codegen positions (declaration, init signature, init body, CodingKeys),
following the existing 'inputprovenance' and 'cleanupbundlemcponrunend'
pattern:
public let adaptermeta: [String: AnyCodable]?
public let paperclip: AnyCodable?
The macOS-side mirror was deleted upstream so only the shared one needs
to be regenerated.
Tests (src/gateway/protocol/agent-params-validator.test.ts, new)
- minimal canonical payload accepted, missing message/idempotencyKey rejected
- root-level paperclip alias accepts object, string, number, boolean, null
- adapterMeta with one or more adapter keys accepted
- empty adapterMeta and adapterMeta with primitive entry values accepted
- both surfaces side by side (paperclip + adapterMeta.paperclip) accepted
- adapterMeta with non-object value rejected (string, number, boolean, null, array)
- truly unknown root properties still rejected (additionalProperties guard intact)
Verification
- pnpm exec oxfmt --check --threads=1 on the touched .ts files: clean.
- Standalone tsx reproducer importing the schema body and compiling it
with the same Ajv configuration as src/gateway/protocol/index.ts:
19/19 cases pass (covering the 8 PR test scenarios above plus their
primitive variants).
- pnpm test src/gateway/protocol/agent-params-validator.test.ts is
expected to pass on CI; local run was blocked by registry access
while preparing the github-pinned @openclaw/fs-safe workspace dep.
Changelog
Added one bullet under ## Unreleased -> ### Changes describing the
namespace + alias and citing openclaw#74635 and openclaw#62102.
Fixes openclaw#74635.
Fixes openclaw#62102.
Refs openclaw#69139, openclaw#72565, openclaw#75901.
Problem
Paperclip ≥ 2026.416.0 includes a
paperclipcontext object in agent wake payloads:{ "message": "wake", "idempotencyKey": "...", "paperclip": { "runId": "run-abc123", "companyId": "13808fb1-...", "agentId": "agent-xyz", "issueId": "issue-001" } }AgentParamsSchemausesadditionalProperties: false, so the gateway rejects these payloads with:This breaks every agent wake triggered by Paperclip ≥ 2026.416.0.
Related: paperclipai/paperclip#4566
Fix
Add
paperclip: Type.Optional(Type.Unknown())toAgentParamsSchema. UsingType.Unknown()(rather than a typed sub-schema) because the shape of the Paperclip context object is Paperclip's concern — the gateway only needs to pass it through without rejection.Tests
Added
src/gateway/protocol/schema/agent.test.tscovering:paperclipcontext object with the standard Paperclip shapepaperclipfield with arbitrary nested shape (forwards-compatible)idempotencyKeymessagepaperclipAll 6 pass.