Exception handling
The build configuration can be faulty in many ways:
- The structure of the build object is invalid
- The properties of the blocks are invalid
- The values of the properties are invalid
In the next sections we will go over the different types of errors that can occur and how to handle them. Each section contains the unique error code you receive - check the exception handling section for more information about exceptions and their unique exception codes.
All builder errors are returned with HTTP status 400 and share the same response shape:
| Property | Type | Description | Default |
|---|---|---|---|
success | boolean | Always false for an error | |
code | integer | The HTTP status code | |
error | string | The unique error code, e.g. RIDDLE_BUILDER_BLOCK_TYPE_INVALID | |
message | string | A human readable description of what went wrong, usually prefixed with the block that caused it | |
validationErrors | array | Only for RIDDLE_BUILDER_BLOCK_PROPERTY_VALUE_VALIDATION - one entry per invalid property |
All builder error codes
| Error code | When it happens |
|---|---|
RIDDLE_BUILDER_BLOCK_TYPE_MISSING | A block object has no type property |
RIDDLE_BUILDER_BLOCK_TYPE_INVALID | A block's type is not a type the current Riddle type supports |
RIDDLE_BUILDER_BLOCK_REQUIRED_PROPERTY_MISSING | A property a block requires was not sent |
RIDDLE_BUILDER_BLOCK_PROPERTY_VALUE_VALIDATION | One or more property values did not pass validation - see validationErrors |
RIDDLE_BUILDER_BLOCK_PROPERTY_VALUE_INVALID | Validation passed, but the value could not be applied when building the block (e.g. it references something that does not exist) |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_INVALID_NODE | A logic node is malformed, e.g. its blockId is missing or not a positive integer |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_NON_EXISTING_BLOCK | A logic node references a block ID the Riddle does not contain |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_INVALID_RULE | An answer rule is invalid, e.g. it names an answer the block does not have |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_NON_UNIQUE_RULES | The same answer is used more than once in the rules of one node |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_CIRCULAR_REFERENCE | The logic tree points back to a block that already appeared earlier in the same path |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_DEAD_ENDS | A logic path ends without leading to a result |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_UNUSED_BLOCKS | The logic tree does not use every block of the Riddle |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_LINEAR_ONLY_ALLOWED | Answer branching was used in a Riddle that only supports a linear flow (e.g. flashcards) |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_CONDITION_INVALID_MAPPABLE | A condition branching node's condition.field does not refer to a value that block offers |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_CONDITION_OPERATOR_NOT_ALLOWED | A condition's operator is not one of the operators allowed for the kind of field its condition.field refers to |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_SCORE_RANGE_OVERLAP | Two score branching ranges overlap, or a range's min is greater than its max |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_DELETED_BLOCK_STILL_REFERENCED | Only when editing a Riddle: a block the request deletes is still referenced by the Riddle's custom logic |
RIDDLE_BUILDER_BLOCK_PROPERTY_LOGIC_RESET_CONFLICT | "logic": {"$reset": true} was combined with other logic configuration in the same object |
Note: Validation may stop at the first validation that fails, so fixing one error can reveal the next one. E.g. errors of a single block, however, are collected and reported together in validationErrors.
Block property validation exception
Error code: RIDDLE_BUILDER_BLOCK_PROPERTY_VALUE_VALIDATION
This error occurs when the value of a property of a block is invalid. The response will contain a validationErrors array with all the errors that occurred.
Example
In this example we use a Predictor build config in which the title is not a string and the items property is missing.
The API returns the following:
{
"success": false,
"code": 400,
"error": "RIDDLE_BUILDER_BLOCK_PROPERTY_VALUE_VALIDATION",
"message": "PredictorPickTheWinnerBlock: Block properties are invalid: Property \"title\": Input is not a string. | PredictorPickTheWinnerBlock: Property \"items\" is required but not set",
"validationErrors": [
{
"message": "Input is not a string.",
"code": "NOT_STRING",
"property": "title"
},
{
"message": "PredictorPickTheWinnerBlock: Property \"items\" is required but not set",
"code": "REQUIRED",
"property": "items"
}
]
}
As you can see the main message of the error names the block that is causing the issue and already lists every concrete problem, separated by |. To handle the errors programmatically, check the validationErrors array instead; each validation error contains a message, code, and property.
Values outside a fixed list
Many properties accept only one of a fixed set of values - a media block's mediaFit, a Recommended Content block's sortBy, a Riddle timer's format, a Placeholder condition's tagMode, and so on. Sending anything else is rejected with the code NOT_ALLOWED_VALUE, and the message names the property and enumerates every accepted value, so you never have to look the list up to fix the call:
{
"success": false,
"code": 400,
"error": "RIDDLE_BUILDER_BLOCK_PROPERTY_VALUE_VALIDATION",
"message": "PresetRiddleTimerBlock: Block properties are invalid: PresetRiddleTimerBlock: Property \"format\" has value \"mm:ss\", which is not an allowed value. Allowed: s, m_s, x_m_x_s.",
"validationErrors": [
{
"message": "PresetRiddleTimerBlock: Property \"format\" has value \"mm:ss\", which is not an allowed value. Allowed: s, m_s, x_m_x_s.",
"code": "NOT_ALLOWED_VALUE",
"property": "format"
}
]
}
This holds for every such property of every block and Riddle type. null is not handled here: a property that may be null still accepts it, and one that may not is reported as the missing/not-nullable error it is, not as a value outside the list.
URLs must be http or https
Every URL a build configuration carries - a result page's redirectUrl, a result builder button's url, a share block's url, an interactive-graphic hotspot's actionUrl/ctaUrl, the DOI confirmationPageUrl, the showcase customQrCodeDestination, an Ad block's iframe url, a personality result's CTA URL, and every media url/attributionUrl/previewImageUrl - ends up in front of a visitor's browser. Only ordinary web addresses are therefore accepted: anything whose scheme is not http or https is rejected with the code UNSUPPORTED_URL_SCHEME, even though it is a syntactically valid URL.
{
"success": false,
"code": 400,
"error": "RIDDLE_BUILDER_BLOCK_PROPERTY_VALUE_VALIDATION",
"message": "ResultRedirectBlock: Block properties are invalid: Property \"redirectUrl\": Only http and https URLs are supported here, got \"ftp\".",
"validationErrors": [
{
"message": "Only http and https URLs are supported here, got \"ftp\".",
"code": "UNSUPPORTED_URL_SCHEME",
"property": "redirectUrl"
}
]
}
A value that is not a URL at all is still reported as the invalid URL it is, not as an unsupported scheme.
Block property value invalid
Error code: RIDDLE_BUILDER_BLOCK_PROPERTY_VALUE_INVALID
This happens if the validation of the properties succeeded but when creating the block the values are invalid. There are too many possible errors to list them all here, but the error message will give you a hint about what went wrong.
Example
Adding an integration with a name which does not exist:
{
"success": false,
"code": 400,
"error": "RIDDLE_BUILDER_BLOCK_PROPERTY_VALUE_INVALID",
"message": "Cannot add \"webhook\" integration with name \"webhook.riddle.com\" to Riddle as it does not exist"
}
Block type missing
If we try to build a Riddle without setting the type property in a Riddle block the API will return the following error:
{
"success": false,
"code": 400,
"error": "RIDDLE_BUILDER_BLOCK_TYPE_MISSING",
"message": "PredictorBuilder: No block type found in block config."
}
In this case the PredictorBuilder throws the exception. This can happen with other embedded blocks as well, e.g. the result page builder blocks.
Block type invalid
Error code: RIDDLE_BUILDER_BLOCK_TYPE_INVALID
The block has a type, but it is not one the surrounding builder supports - for example a Prediction block in a Quiz, or a form field type that is not available via the API:
{
"success": false,
"code": 400,
"error": "RIDDLE_BUILDER_BLOCK_TYPE_INVALID",
"message": "Block type \"Prediction\" not supported in QuizBuilder."
}
For form fields the message additionally lists every type you can use:
{
"success": false,
"code": 400,
"error": "RIDDLE_BUILDER_BLOCK_TYPE_INVALID",
"message": "Form field type \"Signature\" is not allowed in the builder API. Available: Name, Email, Phone, URL, Number, Country, ShortText, LongText, Checkbox, DatePicker, TimePicker, Dropdown, RadioButtons, Rating, Media, Content, Privacy, Captcha"
}
Errors of asynchronous builds
Riddles that are built with queue: true or via the batch endpoint are processed after the response was sent, so none of the errors above can be returned to you - the request answers with an initialized, still empty Riddle instead, and a rejected build configuration simply leaves that Riddle empty.
Build your configuration synchronously (without queue) while you develop it, and only switch to queued or batch builds once it is known to be valid. To check a queued or batch payload before sending it, dry-run it with POST /riddle-builder/validate - it reports the same errors as the table above per item, without creating anything.

