XGR Validation — How validation works
This guide explains what the Validation panel checks, how to read the messages, and why Compile / Deploy / Update Rule is blocked until errors are fixed. It also lists the most common messages you’ll see and how to resolve them.
Where Validation fits into the flow
Validation runs continuously while you edit the model. Compile (step 2) is disabled while errors exist, so the overall flow Wallet → (Compile) → Deploy → Update only continues after Validation is green.
What you see
— Validation panel with a header and an error counter (0 = OK).
What you see (with errors)
— Actionable messages; each line tells you exactly what to change.
What is validated?
A) Contract Reads
functionmust be a non-empty string.args(optional) must be an array of objects shaped like{ type, value }.typemust be one of the XRC‑137 payload types:
string,bool,int64,int256,uint64,uint256,double,decimal,timestamp_ms,duration_ms,uuid,address,bytes,bytes32valuemust be a string (literal, placeholder, CEL, template — all fine).saveAsis required and must be a map (legacy formats are not supported):
{ "0": { key, type, default? }, "1": { key, type, default? } }- indices must be non‑negative integers and unique
keymust follow the Contract Read key naming rule (starts with a letter; then letters/digits plus._-)typemust be one of the XRC‑137 payload types (see list above)default(optional) must match the selectedtyperpc(optional) must be a string URL.save/defaults(legacy fields) are not supported.
Typical errors
- contractReads[i]: "function" must be a non-empty string.
- contractReads[i]: "args" must be an array.
- contractReads[i].args[j] must be an object { type, value }.
- contractReads[i].args[j].type is unknown. Supported: ...
- contractReads[i].args[j].value must be a string.
- contractReads[i]: "save" is not supported anymore. Use "saveAs" map entries only.
- contractReads[i]: legacy "saveAs" string format is not supported anymore. Use a map: { "0": { key, type, default? } }.
- contractReads[i]: "saveAs" must define at least one target.
- contractReads[i].saveAs[j]: key must match ...
- contractReads[i].saveAs[j]: type "..." is unknown. Supported: ...
- contractReads[i].saveAs[j]: default does not match selected type "...".
- contractReads[i]: "defaults" is not supported anymore. Move it into saveAs[<idx>].default.
- contractReads[i]: rpc must be a string URL when provided.
B) APIs
namemust be 1..128 characters, match^[A-Za-z_][A-Za-z0-9_]*$, and be unique across all calls.methodmust beGET | POST | PUT | PATCH.urlTemplaterequired;contentTypemust be"json".headersmust be an object (string → string).timeoutMs(optional) must be a positive integer (milliseconds).extractMaprequired and non‑empty.- aliases must be 1..128 characters and follow the payload naming rule (starts with a letter; then letters/digits)
- aliases must not be duplicated within the same call
- each entry must be either a string RHS (
"resp.user.id") or an object:
{ value, type, default?, save? } valuemust be non-empty- every RHS
valuemust be globally unique across all calls typemust be one of the XRC‑137 payload typesdefault(optional) must match the selectedtypesave(optional) controls whether an alias becomes a stored output (defaults totrue)- Placeholders
[...]insideurlTemplate/bodyTemplateare checked for key syntax and must match^[A-Za-z0-9._-]+$. defaults(optional) must be an object.
Typical errors
- apiCalls[i]: name must be 1..128 characters.
- apiCalls[i]: name must match /^[A-Za-z_][A-Za-z0-9_]*$/.
- apiCalls: duplicate name "users".
- apiCalls[users]: method must be GET|POST|PUT|PATCH.
- apiCalls[users]: urlTemplate is required.
- apiCalls[users]: contentType must be "json".
- apiCalls[users]: headers must be an object (string→string).
- apiCalls[users]: timeoutMs must be a positive integer (milliseconds).
- apiCalls[users]: extractMap must not be empty.
- apiCalls[users]: invalid alias "bad alias".
- apiCalls: value "resp.id" must be unique across all calls.
- apiCalls[users]: alias "price" has unknown type "number". Supported: ...
- apiCalls[users]: extractMap["price"].default does not match type "uint256".
- apiCalls[users]: urlTemplate placeholder [bad key] violates key regex /^[A-Za-z0-9._-]+$/.
- apiCalls[users]: bodyTemplate placeholder [bad key] violates key regex /^[A-Za-z0-9._-]+$/.
- apiCalls[users]: defaults must be an object.
C) Rules / onValid / onInvalid
Validation does not verify that placeholders like [Name] exist or are resolvable at this stage.
What is checked here:
- In onValid.payload and onInvalid.payload, plain output keys (e.g. score) must follow the payload naming rule (starts with a letter; then letters/digits).
- Keys written as placeholders (e.g. "[score]") are accepted as-is (no existence check).
Typical errors
- onValid.payload: invalid key "bad key" – must match ...
- onInvalid.payload: invalid key "bad-key" – must match ...
What you see (example)
— Example messages from payload/schema issues.
D) Base model schema
Core structure checks (payload/rules/outputs) also run. Any schema issues from the XRC‑137 base are surfaced in the same list.
Why Compile/Deploy/Update is blocked
Compile/Deploy/Update stays disabled while any validation error exists. Fix the messages until the counter reaches 0, then the Compile/Deploy/Update button becomes clickable.
What you see (Deploy disabled)
— Deploy button disabled until the error list is empty.
Tip: The flow on the right will still show the next step.
Quick fixes (cheat sheet)
- Contract Reads → Use
saveAsas a map{ "0": { key, type, default? } }; remove legacysave/defaults; ensureargsentries have valid XRC‑137typeand a stringvalue. - API issues → Validate
name/method/urlTemplate/extractMap; keep RHSvalueexpressions unique across all calls; ensure every alias has a supportedtype. - Output keys → In
onValid.payload/onInvalid.payload, keep plain keys in the payload naming rule; placeholders as keys are allowed. - Schema errors → Follow the exact wording; fix the referenced path (index/name).
Last updated: 2026-01-17