openclaw/openclaw · error · Error
ClickClack setup code claim returned invalid v1 contract met
Error message
ClickClack setup code claim returned invalid v1 contract metadata
What it means
The setup-code claim endpoint returned a JSON body that advertised v1 contract metadata (it included either a `contract_version` field, an `api_base_url` field, or both), but the values were malformed: `contract_version` was present and not exactly the number `1`, or `api_base_url` was present and not a string. This guard enforces the v1 wire contract so a half-upgraded or buggy server cannot push an incompatible/typo'd base URL into client config.
Source
Thrown at extensions/clickclack/src/setup-claim.ts:83
if (
allowFrom !== undefined &&
(!Array.isArray(allowFrom) || !allowFrom.every((entry) => typeof entry === "string"))
) {
throw new Error("ClickClack setup code claim returned invalid defaults.allowFrom");
}
if (agentActivity !== undefined && typeof agentActivity !== "boolean") {
throw new Error("ClickClack setup code claim returned invalid defaults.agentActivity");
}
const contractVersion = claim.contract_version;
const apiBaseUrlValue = claim.api_base_url;
const hasContractMetadata = contractVersion !== undefined || apiBaseUrlValue !== undefined;
if (expectedClaimUrl && !hasContractMetadata) {
throw new Error("ClickClack setup code claim returned a legacy response for an exact endpoint");
}
let contract: Pick<ClickClackSetupCodeClaim, "contract_version" | "api_base_url"> = {};
if (hasContractMetadata) {
if (contractVersion !== 1 || typeof apiBaseUrlValue !== "string") {
throw new Error("ClickClack setup code claim returned invalid v1 contract metadata");
}
const apiBaseUrl = requireClickClackSetupApiBaseUrl(
apiBaseUrlValue,
"setup code claim response.api_base_url",
);
const canonicalClaimUrl = buildClickClackSetupClaimUrl(apiBaseUrl);
if (expectedClaimUrl && expectedClaimUrl !== canonicalClaimUrl) {
throw new Error(
"ClickClack setup code claim returned an API base that does not match the claim URL",
);
}
contract = { contract_version: 1, api_base_url: apiBaseUrl };
}
return {
...contract,
token: requireString(claim, "token", "response"),
bot: {
id: requireString(bot, "id", "bot"),View on GitHub (pinned to 01804a7531)
Solutions
- Check the server response body/logs: confirm `contract_version` is exactly `1` (number) and `api_base_url` is a non-empty string.
- Upgrade or downgrade the ClickClack server to match the client's supported v1 contract, or upgrade the openclaw/clickclack plugin to a version that speaks the server's contract.
- If running a custom/mock claim endpoint, return `{"contract_version": 1, "api_base_url": "https://your-host", ...}` exactly.
- File a bug against the server if a real production endpoint returns anything else — the client is correctly refusing an ambiguous response.
Example fix
// Server (claim endpoint) — before
return res.json({ contract_version: "1", api_base_url });
// after
return res.json({ contract_version: 1, api_base_url }); // numeric 1, string url Defensive patterns
Strategy: try-catch
Validate before calling
// Cannot fully validate a server response client-side; you can pre-check the server is reachable. // Pre-flight: GET the claim endpoint's OpenAPI/health if available, or assert the server version matches v1 contract via admin API before invoking setup.
Type guard
// Validates a raw server payload *before* handing it to the parser.
function isV1ContractPayload(v: unknown): v is { contract_version: 1; api_base_url: string } {
return (
!!v && typeof v === 'object' &&
(v as any).contract_version === 1 &&
typeof (v as any).api_base_url === 'string'
);
} Try / catch
try {
const claim = await claimClickClackSetupCode(params);
} catch (e) {
if (e instanceof Error && /invalid v1 contract metadata/.test(e.message)) {
// server spoke a different contract — surface upgrade guidance, do not retry blindly
throw new Error('ClickClack server returned an unsupported contract version. Upgrade the plugin or the server.');
}
throw e;
} Prevention
- Pin client and server to matching released versions.
- Monitor server-side logs for `contract_version`/`api_base_url` shape regressions.
- For mock servers, return exactly `{contract_version: 1, api_base_url: '<string>'}`.
When it happens
Trigger: Server response JSON contains `contract_version: 2` (or `0`, or `"1"` as a string), OR contains `api_base_url: null` / a number / an object, while at least one of the two fields is present. Triggered only when `hasContractMetadata` is true, i.e. either field is defined.
Common situations: ClickClack server was upgraded to a newer contract version the client does not speak yet; server bug returning `api_base_url` as `null` on error paths; a proxy/CDN injected a stub JSON body; client and server version skew after a partial deployment.
Related errors
- ClickClack setup code claim returned an API base that does n
- ClickClack setup code claim failed (${status}): ${detail}
- ClickClack setup URLs must not include a query.
- ClickClack setup URL is missing its #CODE fragment.
- ClickClack --base-url does not match the server in the setup
AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12).
Data as JSON: /api/errors/9877b36c9e9a98c6.
Report an issue: GitHub.