For the complete documentation index, see llms.txt. This page is also available as Markdown.

Troubleshooting

The TACo SDK validates conditions with Zod, and Zod's error messages are precise but terse. This page maps the errors you will actually see to what they mean and how to fix them.

The fastest workflow: run the validator script, copy the error, look it up here (or paste it into an LLM with the building-with-llms guide).

Schema-shape errors

Invalid literal value, expected "and" (or "or", "not")

You wrote "operator": "AND" or "operator": "&&". Operators are lowercase strings. Allowed: "and", "or", "not".

Invalid literal value, expected "compound" (or any other conditionType)

conditionType is wrong or missing. Each condition type has an exact required string — see the schema reference. Common typos: "contractCondition" (should be "contract"), "jsonApi" (should be "json-api"), "ifThenElse" (should be "if-then-else"), "signingAttribute" (should be "signing-attribute").

Required on a field you thought was optional

The schema reference marks required fields with (*). Common surprises:

  • ContractCondition.parameters is required (use [] if the function takes none)

  • ContractCondition.contractAddress is required

  • JsonApiCondition.endpoint is required

  • EcdsaCondition.verifyingKey and curve are required

  • TimeCondition.chain is required (method defaults to "blocktime")

Array must contain at least 2 element(s) on a SequentialCondition

SequentialCondition.conditionVariables requires 2–20 entries. If you only need one variable, you do not need a SequentialCondition — just use the inner condition directly.

Array must contain at most 5 element(s) on a CompoundCondition

CompoundCondition.operands is capped at 5. To express more, embed a SequentialCondition (or nest another MultiCondition, within the shared depth limit — see next).

MultiCondition nesting depth exceeded

Nesting is limited to 4 levels, counted across all MultiConditions collectively: CompoundCondition, IfThenElseCondition, and SequentialCondition. A compound → if-then-else → sequential chain is three levels, even though no single type is nested within itself. If you hit the limit, flatten the policy — often a SequentialCondition with early-exit logic replaces several nested compounds.

String must match pattern /^:[a-zA-Z_][a-zA-Z0-9_]*$/

A context variable name is malformed. They must start with :, followed by a letter or underscore, then letters/digits/underscores. No dots, dashes, spaces, or leading digits. See Context Variables.

Invalid url on JsonApiCondition.endpoint

endpoint must be a literal HTTPS URL. You cannot pass a context variable here. If you need a dynamic endpoint, you must commit to a specific service at encryption time.

Invalid hex string on verifyingKey, contractAddress, etc.

Hex strings must contain only 0-9a-fA-F. verifyingKey (Ed25519/SECP256k1 raw bytes) does not include a 0x prefix; addresses do. Check the schema for which is which.

Logical errors that pass validation but fail at runtime

These do not produce a Zod error — they fail when the network actually evaluates the condition. Symptoms: decryption requests are rejected by Porter or by individual nodes.

"Decryption denied" but the condition looks right

  • Wrong chain ID. A condition that calls Base USDC with "chain": 1 (Ethereum) will hit a contract that does not exist there. Sanity-check every chain ID.

  • Stale block tag. RpcCondition defaults its block tag to "latest", but you can pass "finalized" or "safe". If you used "earliest", you are reading genesis state.

  • Comparator inverted. < vs >= typos are surprisingly common. Re-read the test out loud: "the value must be greater than or equal to X."

"Cannot decode result" from a ContractCondition

The function exists but the outputs array in your functionAbi does not match what the contract actually returns. Double-check against the source contract or a block explorer's verified ABI.

JsonCondition test always fails

Your JSONPath probably does not match. JSONPath is picky:

  • Filter expressions need parens: [?(@.name == "amount")], not [@.name == "amount"].

  • Array element access uses [0], not .0.

  • Test your path against the actual JSON in jsonpath.com before deploying.

SigningObjectAbiAttributeCondition rejects valid calldata

  • Function signature must be exact, including parameter types — transfer(address,uint256) not transfer(address, uint256) (no spaces) and not transfer(address,uint) (uint is invalid; use uint256).

  • For tuple parameters, use (type1,type2,...). Example from the Discord tipping bot deep-dive: execute((address,uint256,bytes)).

  • subIndices walk into nested structures one level at a time. For a tuple (address, uint256, bytes), subIndices: [2] selects the bytes field.

SequentialCondition variable not found

You wrote :varname but the bound varName was varName (no leading colon, case-sensitive). The binding uses the bare name; the reference uses : + name.

When all else fails

  1. Run validate-conditions.ts and read the full error in validation-error.txt.

  2. Compare against the closest example in the cookbook.

  3. Paste the error + your condition + the schema reference URL into an LLM. See Building Conditions with an LLM.

  4. Test end-to-end against a local testnet (see Quickstart) or your own integration.

Last updated