This page provides a comprehensive reference for problem type URIs used by Tourfold REST APIs. These follow RFC 9457 and include machine-readable URIs.
GraphQL errors are different: they are returned in GraphQL's errors array rather than as an HTTP problem document. Errors Tourfold raises carry the same Type URI in extensions.code that a REST error carries in type; errors raised by the GraphQL engine while parsing or validating a document carry no extensions.code at all. See GraphQL Errors.
Error Type Structure​
Error types follow this structure:
- Category errors:
https://problems.tourfold.com/{error-slug} (e.g., https://problems.tourfold.com/validation-failed)
- Namespaced errors:
https://problems.tourfold.com/{category}/{error-slug} (e.g., https://problems.tourfold.com/tours/tour-ended)
Generic Errors​
These errors are general-purpose and can occur across the API.
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/unknown-error | Unknown error | An unexpected error occurred | 500 |
https://problems.tourfold.com/invalid-input | Invalid input | The provided input was not valid | 400 |
https://problems.tourfold.com/business-rule-violation | Business rule violation | The request violates business rules | 422 |
https://problems.tourfold.com/not-found | Not found | The requested resource was not found | 404 |
https://problems.tourfold.com/method-not-allowed | Method not allowed | The path exists, but the requested HTTP method is not supported. The Allow header and data.supported list the supported methods. | 405 |
https://problems.tourfold.com/not-acceptable | Not acceptable | No representation of the resource matches the Accept header | 406 |
https://problems.tourfold.com/unsupported-media-type | Unsupported media type | The request body's media type is not accepted. data.content_type contains the rejected value and data.supported lists accepted media types. | 415 |
https://problems.tourfold.com/authentication-required | Authentication required | Valid authentication credentials are required. The cause is surfaced in data.reason (token_missing, token_expired, token_invalid) and mirrored in the WWW-Authenticate header. | 401 |
https://problems.tourfold.com/access-denied | Access denied | You don't have permission to perform this action. The cause is surfaced in data.reason (missing_grant, not_owner, not_author, not_member, plan_restricted, tenant_scope, resource_locked); grant-based denials also carry data.required_grants when the required grants are statically known. | 403 |
https://problems.tourfold.com/tenant-disabled | Tenant disabled | This tenant is disabled | 403 |
https://problems.tourfold.com/tenant-billing-locked | Tenant billing locked | This tenant is locked because billing requires attention | 402 |
https://problems.tourfold.com/action-not-allowed | Action not allowed | This action is not allowed | 403 |
https://problems.tourfold.com/validation-failed | Validation failed | One or more fields failed validation | 422 |
https://problems.tourfold.com/resource-conflict | Resource conflict | The request conflicts with the current state | 409 |
https://problems.tourfold.com/rate-limit-exceeded | Rate limit exceeded | Rate limit exceeded for this endpoint | 429 |
https://problems.tourfold.com/too-many-requests | Too many requests | Too many requests in the time window | 429 |
https://problems.tourfold.com/burst-limit-exceeded | Burst limit exceeded | Burst rate limit exceeded | 429 |
https://problems.tourfold.com/illegal-argument | Illegal argument | An illegal argument was provided | 422 |
https://problems.tourfold.com/not-unique | Not unique | The provided details were not unique | 422 |
https://problems.tourfold.com/payload-too-large | Payload too large | The request payload exceeds the maximum allowed size | 413 |
https://problems.tourfold.com/not-implemented | Not implemented | This functionality is not implemented | 501 |
https://problems.tourfold.com/upstream-service-unavailable | Upstream service unavailable | An upstream service is temporarily unavailable | 503 |
https://problems.tourfold.com/login-failed | Login failed | Authentication credentials are invalid. Returned for a rejected credential-based login, as opposed to an absent or unusable bearer token (authentication-required). | 401 |
https://problems.tourfold.com/client-connection-broken | Client connection broken | The client connection was interrupted | 500 |
https://problems.tourfold.com/empty-collection-argument | Empty collection argument | The provided collection argument must not be empty | 422 |
Generic Error Examples​
{
"type": "https://problems.tourfold.com/validation-failed",
"title": "Validation failed",
"detail": "One or more fields failed validation",
"status": 422
}
{
"type": "https://problems.tourfold.com/not-found",
"title": "Not found",
"detail": "The requested resource was not found",
"status": 404
}
Validation Sub-Problem Types​
A top-level validation-failed problem can contain an errors[] array. Each entry uses one of
these stable, cross-feature type URIs when the standard meaning applies. Its pointer identifies
the rejected request field using JSON Pointer syntax. Feature-specific validation types are
documented in their feature section instead.
| Type URI | Meaning |
|---|
https://problems.tourfold.com/field-validation-error | The field failed validation and no narrower standard type applies. |
https://problems.tourfold.com/field-required | The field is missing, null, empty, or blank. |
https://problems.tourfold.com/field-too-large | A numeric value is above its allowed maximum. |
https://problems.tourfold.com/field-too-small | A numeric value is below its allowed minimum. |
https://problems.tourfold.com/field-size-invalid | A string or collection length is outside its allowed bounds. |
https://problems.tourfold.com/field-type-invalid | The value has the wrong JSON type or shape. |
https://problems.tourfold.com/field-out-of-range | The value is outside the field's allowed range. |
https://problems.tourfold.com/invalid-email | The value is not a valid email address. |
https://problems.tourfold.com/invalid-phone-number | The value is not a valid international phone number. |
https://problems.tourfold.com/invalid-enum-value | The value is not one of the allowed enum members. |
https://problems.tourfold.com/not-unique | The value duplicates a record whose field must be unique. |
GraphQL Errors​
These surface inside the GraphQL response envelope, not as an HTTP problem document: a GraphQL failure
is still HTTP 200 with an errors array.
Which errors carry a code. Every error Tourfold raises carries extensions.code — the Type URI, the
same value a REST error carries in type — so both surfaces are keyed off one identifier. title and (when present) data sit flat beside it; there is deliberately no
wrapping problem object, matching Shopify and GitHub. The human text lives in message and is not
repeated as detail.
Errors raised by the GraphQL engine itself — a malformed document, an unknown field, a wrongly typed
argument — carry no extensions.code, because they are produced before any Tourfold code runs. Branch on
extensions.code when it is present and fall back to message when it is not; never assume every entry
in errors has a code.
The graphql/ namespace is not the whole catalog. Only failures with no REST equivalent take it.
Everything else reuses the type it already has elsewhere on this page — a rejected filter value is
validation-failed, with the offending field named under extensions.errors, and an unexpected
server-side failure is unknown-error. A client that already handles Tourfold's REST errors needs no
second vocabulary for GraphQL.
There is no status field, unlike the REST tables on this page. The response is always HTTP 200,
so there would be no status to report; match on code instead.
An error may list sub-errors under extensions.errors. These carry only what varies per occurrence
(code, message, path, data) and do not nest further. path addresses a field the way GraphQL
addresses everything else, so one payload never mixes field paths with JSON Pointers; converting to a
REST problem document renders it as an RFC 6901 pointer.
| Type URI | Title | Description |
|---|
https://problems.tourfold.com/graphql/query-too-deep | Query too deep | The query nests more levels than the configured maximum depth |
https://problems.tourfold.com/graphql/query-too-complex | Query too complex | The query is estimated to materialise more rows than the configured budget allows |
https://problems.tourfold.com/graphql/filter-too-deep | Filter too deep | The where argument nests more levels than the configured maximum filter depth |
https://problems.tourfold.com/graphql/invalid-cursor | Invalid cursor | The supplied pagination cursor was not produced by this API |
https://problems.tourfold.com/graphql/invalid-pagination | Invalid pagination arguments | The supplied pagination arguments are contradictory or out of range |
Each reports in data what a client needs in order to adapt without guessing: the two limit errors give
the measured value next to the limit, invalid-cursor echoes the cursor it rejected, and
invalid-pagination echoes the arguments that conflicted.
{
"data": null,
"errors": [
{
"message": "Query is estimated to materialise 3003001 rows, above the budget of 100000. A connection multiplies its subtree by its page size — request smaller pages or select fewer nested fields.",
"extensions": {
"code": "https://problems.tourfold.com/graphql/query-too-complex",
"title": "Query too complex",
"data": { "cost": 3003001, "limit": 100000 }
}
}
]
}
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/pagination/invalid-page-number | Invalid page number | Page number must be non-negative (0 or greater) | 422 |
https://problems.tourfold.com/pagination/invalid-page-size | Invalid page size | Page size must be between 1 and 1000 | 422 |
Time Range Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/time-range/from-after-to | Invalid time range | The 'from' parameter must be before the 'to' parameter | 422 |
Activity Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/activities/wrong-activity-type | Wrong activity type | Wrong activity type | 422 |
AI Assistant Errors​
These errors come from the in-app AI assistant ("Ask Rob"). They surface both as HTTP error responses (REST endpoints under /frontend/v2/ai-assistant/...) and inside the turn.error SSE event payload as an embedded ProblemDetail — the wire shape is identical.
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/ai-assistant/assistant-disabled | AI assistant is disabled | The AI assistant is disabled for this tenant. A tenant administrator can re-enable it from the AI assistant settings. | 403 |
https://problems.tourfold.com/ai-assistant/turn-in-progress | AI assistant turn already in progress | Another AI assistant turn is already in progress for this session. Wait for it to finish or cancel it before sending another message. The conflicting sessionId is included in data. | 409 |
https://problems.tourfold.com/ai-assistant/provider-rate-limited | AI assistant provider is rate limited | The AI assistant is temporarily at capacity because the upstream AI provider rejected the turn for a capacity reason on the shared key (rate limit, overload, or account quota) — not the tenant's own spend budget. The message can be retried after a short wait. | 503 |
Address Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/addresses/opening-hours-wrong-format | Opening hours wrong format | Opening hours have a wrong time format | 422 |
Filestore/File Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/filestore/file-not-found | File not found | The referenced file or rendition is not available. | 404 |
https://problems.tourfold.com/filestore/file-deleted | File deleted | The referenced file has been deleted. | 422 |
https://problems.tourfold.com/filestore/storage-object-missing | Storage object missing | The file is recorded as uploaded, but its underlying object is missing from storage — a data-integrity gap, distinct from a never-existed id (404). The data payload names the offending object: bucket, storageKey, and — on rendition read paths — fileId, renditionId, alias. | 410 |
https://problems.tourfold.com/filestore/file-not-attachable | File is not attachable | Collapsed 404 covering every "you can't use this file" failure (id does not exist, wrong source key, wrong uploader, already linked). The collapse is intentional — UUID leaks are the threat model. | 404 |
https://problems.tourfold.com/filestore/rendition-source-not-supported | Rendition source not supported | Renditions can only be generated from image and PDF sources. | 422 |
https://problems.tourfold.com/filestore/rendition-target-format-not-supported | Rendition target format not supported | The requested target format is not supported by the source-specific rendition converter. | 422 |
https://problems.tourfold.com/filestore/rendition-source-decode-failed | Rendition source decode failed | The source file could not be decoded for rendition generation (corrupted or unsupported encoding). | 422 |
https://problems.tourfold.com/filestore/rendition-pdf-empty | Rendition source PDF is empty | The source PDF has no pages. | 422 |
https://problems.tourfold.com/filestore/rendition-alias-reserved | Rendition alias is reserved | The alias original is reserved for the canonical original rendition. | 422 |
https://problems.tourfold.com/filestore/upload-content-empty | Upload content is empty | The upload payload is empty. | 422 |
https://problems.tourfold.com/filestore/upload-mime-type-blank | Upload MIME type is missing | A non-blank MIME type is required for the upload. | 422 |
https://problems.tourfold.com/filestore/upload-original-file-name-blank | Upload original file name is missing | A non-blank original file name is required for the upload. | 422 |
https://problems.tourfold.com/filestore/upload-rejected | Upload rejected | The upload was rejected during completion — size or MIME type does not match the declared values. | 422 |
https://problems.tourfold.com/filestore/invalid-tenant-public-id | Invalid tenant public id | The tenant_public_id path token must be <tenantId>.<publicId> with both segments being valid UUIDs. | 422 |
https://problems.tourfold.com/filestore/storage-purge-incomplete | Storage purge incomplete | A bulk purge could not delete every matching object after retries; some objects remain in storage. The data payload names the bucket, prefix, and undeletedCount. | 500 |
Usage Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/usage/limit-exceeded | Usage limit exceeded | The requested operation would exceed the tenant's configured usage limit | 422 |
https://problems.tourfold.com/usage/configuration-invalid | Usage configuration invalid | Usage metering is not configured correctly for this tenant or meter | 422 |
Document Management Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/document-management/invalid-name | Invalid name | The supplied folder or document name is invalid (empty after trim, reserved name, forbidden character, or exceeds the length limit). | 422 |
https://problems.tourfold.com/document-management/name-taken | Name taken | A live sibling folder or document already uses this name. | 409 |
https://problems.tourfold.com/document-management/parent-not-found | Parent folder not found | The referenced parent folder does not exist. | 404 |
https://problems.tourfold.com/document-management/folder-not-found | Folder not found | The referenced folder does not exist. | 404 |
https://problems.tourfold.com/document-management/move-into-descendant | Move into descendant | A folder cannot be moved into itself or one of its descendants. | 422 |
https://problems.tourfold.com/document-management/move-across-managed-boundary | Move across managed boundary | A user folder cannot be moved into a managed subtree (e.g. /objects/...), and a managed folder cannot be moved out of one. | 400 |
https://problems.tourfold.com/document-management/invalid-move-target | Invalid move target | The target folder for a document move is not allowed (missing or a managed_branch structural folder). The reason is surfaced in data.reason. | 422 |
https://problems.tourfold.com/document-management/must-be-soft-deleted-first | Must be soft-deleted first | The document must be soft-deleted (moved to the user's Trash) before it can be permanently deleted (hard-deleted). | 409 |
https://problems.tourfold.com/document-management/cannot-modify-managed-folder | Cannot modify managed folder | This folder is managed by the system (object root or system root) and cannot be renamed, moved, or deleted. | 403 |
https://problems.tourfold.com/document-management/cannot-modify-soft-deleted-document | Cannot modify soft-deleted document | The document is soft-deleted (in the user's Trash) and read-only. Only restore and hard-delete are allowed; rename, description, move, tag, star, new-version upload, and AI analyze are rejected with this type. Folders are never soft-deleted in the new model so there is no folder counterpart. | 409 |
https://problems.tourfold.com/document-management/document-not-found | Document not found | The referenced document does not exist or is soft-deleted. | 404 |
https://problems.tourfold.com/document-management/version-not-found | Document version not found | The referenced document version does not exist, belongs to a different document, or has not been finalized yet. | 404 |
https://problems.tourfold.com/document-management/version-mime-mismatch | Version MIME mismatch | A new version must use the same MIME type as the existing document. Expected and actual types are surfaced in data.expected and data.actual. | 422 |
https://problems.tourfold.com/document-management/invalid-download-rendition | Unsupported download rendition | The rendition query parameter must be one of the supported aliases. Allowed values are surfaced in data.allowed; the rejected value is in data.value. | 422 |
https://problems.tourfold.com/document-management/upload-initiate-failed | Upload initiate failed | The upload could not be initiated. The cause (filestore validation rejected the MIME or size, or another filestore error) is in data.cause and the response sub-problems. | 422 |
https://problems.tourfold.com/document-management/upload-finalize-failed | Upload finalize failed | The upload could not be finalized. The cause (missing storage key, no pending version, or a filestore error) is included in the response sub-problems. | 422 |
https://problems.tourfold.com/document-management/extraction-not-found | Extraction not found | The referenced extraction does not exist, or it does not belong to a document-management document. | 404 |
https://problems.tourfold.com/document-management/invalid-retention-days | Invalid retention days | The document-management auto-hard-delete retention value is outside the allowed range. The rejected value and bounds are surfaced in data.value, data.min, and data.max. | 422 |
Returned by the polymorphic comments API under /api/v2/comments. Body-validation errors carry sub-problems pointing at the offending JSON pointer (#/body_markdown, #/edit_reason, etc.).
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/comments/target-not-found | Target not found | The supplied target_type / target_id does not resolve to an existing object the caller can see. Reserved for the Phase 5 ACL-inheritance check; not currently thrown. | 404 |
https://problems.tourfold.com/comments/parent-comment-not-found | Parent comment not found | The supplied parent_comment_id does not resolve to an existing comment. | 404 |
https://problems.tourfold.com/comments/parent-target-mismatch | Parent comment is on a different target | The supplied parent_comment_id belongs to a different (target_type, target_id) than the new comment. | 422 |
https://problems.tourfold.com/comments/body-too-long | Comment body too long | body_markdown exceeds the configured maximum length. The cap is surfaced in data.max_length. | 422 |
https://problems.tourfold.com/comments/body-invalid-markdown | Comment body contains disallowed markdown | body_markdown contains constructs that are not on the comments allow-list (headings, raw HTML, images, non-http(s) link schemes, etc.). The offending constructs are listed as sub-problems with line_number pointers when available. | 422 |
https://problems.tourfold.com/comments/comment-not-found | Comment not found | The referenced comment does not exist (or has been hard-deleted). | 404 |
https://problems.tourfold.com/comments/cannot-edit-others | Cannot edit another user's comment | Editing a comment authored by another user requires the comments:update grant. | 403 |
https://problems.tourfold.com/comments/cannot-delete-others | Cannot delete another user's comment | Deleting a comment authored by another user requires the comments:delete grant. | 403 |
https://problems.tourfold.com/comments/moderation-reason-required | Moderation edit requires a reason | Editing another user's comment under the comments:update grant requires a non-blank edit_reason. | 422 |
https://problems.tourfold.com/comments/cannot-restore-not-deleted | Comment is not soft-deleted | Only soft-deleted comments can be restored; the referenced comment is currently live. | 422 |
https://problems.tourfold.com/comments/read-cursor-target-mismatch | Comment does not belong to the supplied target | comment_id in mark-read-until does not belong to the supplied (target_type, target_id). | 422 |
https://problems.tourfold.com/comments/mention-type-unknown | Unknown mention type | A mention token uses a type prefix the server does not understand. | 422 |
https://problems.tourfold.com/comments/mention-target-not-found | Mention target not found | No mention target matches the supplied (type, id) in the current tenant. | 404 |
https://problems.tourfold.com/comments/reaction-on-deleted-comment | Cannot react to a deleted comment | The referenced comment is soft-deleted; reactions can only be added to live comments. | 422 |
https://problems.tourfold.com/comments/reaction-not-found | Reaction not found | DELETE /api/v2/comments/{id}/reactions/{reaction_id} was called with an id that does not exist or that belongs to a different user. Returned identically in both cases so the surface does not leak the existence of other users' reaction rows. | 404 |
https://problems.tourfold.com/comments/attachment-mime-not-allowed | Attachment MIME type is not allowed | The uploaded file's MIME is on the comments attachment denylist (e.g. image/svg+xml, executable formats). The rejected MIME and the full denylist are surfaced in data.mime_type / data.blocked_mime_types. | 422 |
https://problems.tourfold.com/comments/attachment-too-large | Attachment exceeds per-file size limit | The uploaded file exceeds comments.attachments.max-bytes-per-file. The requested and maximum sizes are surfaced in data.requested_bytes / data.max_bytes. | 422 |
https://problems.tourfold.com/comments/attachment-storage-limit-exceeded | Tenant storage allowance exceeded | The upload would push the tenant past its storage allowance. The underlying billing problem type and quantities are surfaced in data.underlying_problem_type / data.underlying_data. | 422 |
https://problems.tourfold.com/comments/attachment-not-found | Comment attachment not found | The referenced attachment_id does not exist, has been hard-deleted, or has no original rendition. | 404 |
https://problems.tourfold.com/comments/attachment-blob-gone | Attachment blob has been removed | GET /api/v2/comments/attachments/{attachment_id}/download-url was called for an attachment whose underlying blob has been hard-deleted (target cascade, manual purge, orphan-cleanup gap). The attachment still appears on the comment with is_deleted=true; only the presigned-URL refresh surface returns 410. | 410 |
https://problems.tourfold.com/comments/attachment-not-from-comments | Attachment was uploaded for a different feature | The referenced file's source_key is not COMMENT_ATTACHMENTS — cross-feature blob reuse is rejected. The actual source key is surfaced in data.source_key. | 422 |
https://problems.tourfold.com/comments/attachment-upload-incomplete | Attachment upload not yet completed | The referenced file exists but its original rendition is not in UPLOADED status. The current status is surfaced in data.upload_status. | 422 |
https://problems.tourfold.com/comments/attachment-mime-not-inline-previewable | Attachment cannot be referenced inline | A  body reference targets a file whose MIME is not on the inline-previewable list (e.g. PDF cannot be embedded as <img>). Attach as a chip instead. The MIME is surfaced in data.mime_type. | 422 |
https://problems.tourfold.com/comments/attachment-inline-not-linked | Inline reference not present in attachment list | The comment body references attachment:<uuid> for a file that is not in the request's attachment_ids array. The first unreferenced id is in data.attachment_id; the full set is in data.all_unlinked_attachment_ids. | 422 |
https://problems.tourfold.com/comments/attachment-inline-invalid-uri | Malformed attachment: reference in body | An image destination uses the attachment: scheme but the suffix is not a valid UUID. | 422 |
https://problems.tourfold.com/comments/too-many-attachments | Comment exceeds attachment count limit | The request carries more than comments.attachments.max-per-comment files. The cap and the requested count are surfaced in data.max_per_comment / data.requested. | 422 |
https://problems.tourfold.com/comments/attachment-already-linked | Attachment is linked to a posted comment | DELETE /api/v2/comments/attachments/uploads/{attachment_id} was called for an attachment already linked to a comment. The proper removal path is the comment update/delete endpoint, which cascades the underlying blob through the existing hard-delete hook. | 409 |
Notifications Errors​
Returned by the notification inbox under /frontend/v2/notifications and by NotificationEmitter.emit(...) calls from other features. invalid-action-url is enforced server-side both when an operator authors a system notification in the admin app and when a feature emits an in-app notification, so a malformed or non-https:// link cannot reach the client renderer.
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/notifications/notification-not-found | Notification not found | The referenced notification does not exist, has expired, or does not belong to the caller. Returned identically for "no such id", "expired", and "belongs to another user" so the surface does not leak the existence of other users' rows. | 404 |
https://problems.tourfold.com/notifications/invalid-action-url | Notification action URL is not allowed | action_url must be a relative path starting with / or an absolute https:// URL. Other schemes (javascript:, data:, vbscript:, file:), scheme-relative URLs (//evil.com/x), and malformed URIs are rejected. The offending value is surfaced in data.action_url. | 422 |
Custom Domains Errors​
Returned by the workspace custom-domains API under /frontend/v2/custom-domains. The verify endpoint runs the TXT + CNAME DNS checks and returns this problem type on any DNS-side mismatch. Per-record details (which record failed, the expected value, the actually-resolved CNAME targets) live in the errors[] array as sub-problems with errorType slugs custom-domain-txt-record-missing and custom-domain-cname-record-mismatch (sub-problems aren't standalone ProblemType enums — they carry the same RFC 9457 shape but are scoped to the parent verification-failed problem). The frontend matches on the sub-problem type URI to colour the failing card.
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/custom-domains/verification-failed | Custom domain verification failed | DNS records required to verify the custom domain are missing or incorrect. errors[] contains per-record sub-problems (custom-domain-txt-record-missing and/or custom-domain-cname-record-mismatch) with the expected values in data.expected_record_name / data.expected_record_value / data.expected_record_target and, for CNAME, the actually-resolved targets in data.actual_targets. The row is still persisted with status = VERIFICATION_FAILED and the latest last_verification_error. | 422 |
Audit Log Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/audit-logs/invalid-time-range | Invalid time range | The 'from' time must be before the 'to' time | 422 |
https://problems.tourfold.com/audit-logs/invalid-sort | Invalid sort parameter | Sorting field or direction is not supported | 422 |
Case Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/cases/cases-active | Cases active | Cases are currently active | 422 |
https://problems.tourfold.com/cases/case-already-assigned | Case already assigned | The case is already assigned | 422 |
https://problems.tourfold.com/cases/action-not-allowed | Action not allowed | This action is not allowed on the case | 422 |
https://problems.tourfold.com/cases/confirmation-present | Confirmation present | Case confirmation is already present | 422 |
https://problems.tourfold.com/cases/case-finished | Case finished | The case is finished | 422 |
https://problems.tourfold.com/cases/not-approved | Case not approved | The case is not approved | 422 |
https://problems.tourfold.com/cases/oeamtc-missing-id | Missing OEAMTC Case ID | OEAMTC Case ID is missing | 422 |
https://problems.tourfold.com/cases/oeamtc-update-failed | Cannot update OEAMTC Case | Failed to update OEAMTC case | 422 |
https://problems.tourfold.com/cases/oeamtc-not-found | OEAMTC Case not found | OEAMTC Case was not found | 404 |
Device Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/device/platform-error | Platform error | Device platform error | 422 |
https://problems.tourfold.com/device/registered-to-another-workspace | Device registered to another workspace | This device id is already registered to another workspace | 409 |
https://problems.tourfold.com/device/device-disabled | Device disabled | This device is disabled and cannot receive telemetry | 403 |
https://problems.tourfold.com/device/device-has-active-tour | Device has active tour | Device is associated with a vehicle that currently has an active tour | 422 |
Document Analyzer Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/document-analyzer/schema-invalid | Schema is not valid | The supplied schema could not be parsed as a JSON Schema (Draft 2020-12). | 422 |
https://problems.tourfold.com/document-analyzer/url-not-https | URL must use HTTPS | The document URL must use HTTPS. | 422 |
https://problems.tourfold.com/document-analyzer/url-host-not-allowed | URL host is not allowed | The document URL host is not in the configured allow-list. Submit a URL pointing at an allowed host (typically a presigned filestore URL). | 422 |
https://problems.tourfold.com/document-analyzer/unsupported-media-type | Media type not supported | The declared media type is not supported by the document analyzer. | 422 |
https://problems.tourfold.com/document-analyzer/job-not-found | Job not found | No document analysis job with that id exists in the current tenant. | 404 |
https://problems.tourfold.com/document-analyzer/url-fetch-failed | Could not fetch document URL | The document URL could not be fetched. | 422 |
https://problems.tourfold.com/document-analyzer/document-too-large | Document is too large | The fetched document exceeded the maximum size allowed by the document analyzer. | 422 |
https://problems.tourfold.com/document-analyzer/media-type-mismatch | Document content does not match declared media type | The declared media type does not match the actual document content. | 422 |
https://problems.tourfold.com/document-analyzer/model-output-does-not-match-schema | Model output did not match the schema | The model could not produce a response that conforms to the supplied or inferred JSON Schema. | 422 |
https://problems.tourfold.com/document-analyzer/schema-inference-failed | Could not infer a valid schema from the document | The model could not produce a valid JSON Schema (Draft 2020-12) for the document. Submit again with an explicit schema. | 422 |
https://problems.tourfold.com/document-analyzer/provider-unavailable | Model provider is unavailable | The upstream model provider is unavailable. Retry the job; if the failure persists, contact support. | 503 |
Geocoding Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/geocoding/no-results | No results | Geocoding returned no results | 404 |
Message Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/messages/acknowledged-by-field-empty | Invalid Input | acknowledgedBy field can't be empty | 422 |
Skill Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/skills/not-found | Skill not found | Skill was not found | 404 |
https://problems.tourfold.com/skills/shortkey-not-found | Shortkey not found | Skill shortkey not found | 404 |
SMS Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/sms/send-error | SMS send error | Error sending SMS | 500 |
Tag Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/tags/not-found | Tag not found | Tag with the given id was not found | 404 |
https://problems.tourfold.com/tags/tag-already-associated | Tag already associated | This tag is already associated with the given resource | 409 |
Template Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/templates/not-found | Template not found | Template was not found | 404 |
https://problems.tourfold.com/templates/invalid | Template invalid | Template is not valid | 500 |
https://problems.tourfold.com/templates/rendering-error | Rendering error | Error rendering PDF template | 500 |
https://problems.tourfold.com/templates/todo-not-found | Todo template not found | Todo template was not found | 404 |
Tenant Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/tenants/not-found | Tenant not found | Tenant was not found | 404 |
https://problems.tourfold.com/tenants/template-name-invalid | Invalid template name | Template name must start with 'template_' | 422 |
https://problems.tourfold.com/tenants/source-tenant-is-frozen | Source tenant is frozen | Cannot clone a frozen template tenant as a new template | 422 |
https://problems.tourfold.com/tenants/realm-mode-migration-not-allowed | Realm-mode migration not allowed | Only the SHARED → DEDICATED realm-mode migration is supported. | 422 |
Tenant Reset Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/tenant-reset/reset-not-allowed | Reset not allowed | This workspace cannot be reset. Ask an administrator to enable resets first | 403 |
https://problems.tourfold.com/tenant-reset/active-tours-present | Active tours in progress | This workspace has tours in progress. Finish or cancel them before resetting | 409 |
https://problems.tourfold.com/tenant-reset/no-pending-reset-request | No pending reset request | There is no pending reset to confirm. Request a confirmation code first | 404 |
https://problems.tourfold.com/tenant-reset/invalid-confirmation-code | Invalid confirmation code | The confirmation code provided is not valid | 422 |
https://problems.tourfold.com/tenant-reset/confirmation-code-expired | Confirmation code expired | The confirmation code has expired. Please request a new one | 422 |
https://problems.tourfold.com/tenant-reset/template-not-active | Template not active | The selected template is not available. Choose one of the active templates | 422 |
https://problems.tourfold.com/tenant-reset/confirmation-email-rate-limited | Confirmation email rate limited | Please wait before requesting another confirmation code | 429 |
https://problems.tourfold.com/tenant-reset/owner-email-unavailable | Owner email unavailable | The workspace owner has no email address on file to send the confirmation code to | 422 |
https://problems.tourfold.com/tenant-reset/reset-failed | Reset failed | The workspace could not be reset. Your confirmation code is still valid — please try again | 500 |
Tenant Template Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/tenant-templates/template-not-found | Template not found | The requested tenant template does not exist | 404 |
https://problems.tourfold.com/tenant-templates/tenant-not-frozen | Tenant is not a frozen template | The tenant_id_to_clone must reference a frozen tenant (name starts with 'template_') | 422 |
Todo Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/todos/not-found | Todo not found | Todo was not found | 404 |
Tour Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/tours/tour-ended | Tour ended | The tour has already ended | 422 |
https://problems.tourfold.com/tours/tour-not-accepting-cases | Tour not accepting cases | This tour is not accepting new cases | 422 |
https://problems.tourfold.com/tours/capacity-reached | Capacity reached | The tour has reached its workload capacity | 422 |
https://problems.tourfold.com/tours/no-user-associated | No user associated | No user is associated with this tour | 422 |
https://problems.tourfold.com/tours/invalid-lea-tours | Invalid LEA tours | Wrong number of LEA tours | 500 |
https://problems.tourfold.com/tours/cannot-duplicate-finished | Cannot duplicate finished | Cannot duplicate a finished tour | 500 |
https://problems.tourfold.com/tours/association-conflict | Association conflict | Tour case association conflict | 409 |
https://problems.tourfold.com/tours/start-time-after-end | Start time after end | Start time must be before scheduled end | 422 |
https://problems.tourfold.com/tours/tour-has-unfinished-activities | Tour has unfinished activities | Cannot finish tour with activities in PENDING or STARTED status | 409 |
User Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/users/password-error | Password error | Password could not be set | 422 |
https://problems.tourfold.com/users/already-assigned | User already assigned | User is already assigned | 422 |
https://problems.tourfold.com/users/token-not-valid | Token not valid | The provided token is not valid | 422 |
https://problems.tourfold.com/users/tokens-not-found | Tokens not found | No tokens were found | 404 |
https://problems.tourfold.com/users/not-tenant-owner | Not the workspace owner | Only the current workspace owner can perform this action — e.g. transferring ownership. Distinct from access-denied because it is terminal: no grant can make a non-owner the owner, so do not prompt the user to request permissions. Carries data.reason: not_owner. | 403 |
Vehicle Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/vehicles/no-active-device-association | No active device association | No active vehicle device association found | 422 |
https://problems.tourfold.com/vehicles/no-device-association | No device association | No vehicle device association found | 422 |
https://problems.tourfold.com/vehicles/vehicle-already-assigned | Vehicle already assigned | Vehicle is already assigned | 422 |
https://problems.tourfold.com/vehicles/vehicle-has-active-tour | Vehicle has active tour | Vehicle currently has an active tour | 422 |
https://problems.tourfold.com/vehicles/vehicle-not-associated | Vehicle not associated | Vehicle is not associated | 422 |
https://problems.tourfold.com/vehicles/vehicle-type-not-found | Vehicle type not found | Referenced vehicle type does not exist | 422 |
Custom Objects Errors​
Custom Objects uses generic problem types (not-found, invalid-input, validation-failed, unknown-error) at the top level. The specific error context is conveyed through field validation error types in the errors array of the response body.
Top-Level Problem Types​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/not-found | Not found | Definition, instance, or relation was not found | 404 |
https://problems.tourfold.com/invalid-input | Invalid input | The request body could not be parsed (e.g., malformed or unparseable JSON) | 400 |
https://problems.tourfold.com/validation-failed | Validation failed | Schema or instance validation failed | 422 |
https://problems.tourfold.com/payload-too-large | Payload too large | Request payload exceeds the maximum allowed size | 413 |
https://problems.tourfold.com/unknown-error | Unknown error | An unexpected error occurred (e.g., DDL change failure) | 500 |
Definition-Level Protection​
When a PUT or DELETE is attempted on a protected definition, the request is rejected before schema validation runs. The error is a top-level validation-failed response (HTTP 422) — no errors array is present. The detail field distinguishes the two cases:
| Scenario | detail value |
|---|
Definition has readOnly: true (e.g. tour, case, activity) | "The definition of '<slug>' is read only." |
Definition has builtIn: true but is not read-only (e.g. location) | "The definition of '<slug>' is a built-in definition and cannot be modified." |
Definition & Schema Validation Error Types​
These appear as errorType values inside the errors array when a definition create or update request fails validation.
| Error Type | Description |
|---|
title-required | Title is required for a definition |
invalid-slug | Slug format is invalid |
slug-already-exists | A definition with the same slug already exists |
slug-reserved | Slug is reserved for a built-in or read-only definition and cannot be reused |
read-only-schema | A system property (e.g. id, created_at) on the definition has its readOnly flag removed or set to false, which is not permitted |
invalid-schema-structure | Schema violates JSON Schema 2020-12 meta-schema. In fallback parser/error paths, detail can be: Schema is incorrect and requires updating, please update the schema for slug '<slug>' |
schema-too-deeply-nested | Schema has excessive nesting depth |
definition-payload-too-large | schema payload exceeds the configured max size (HTTP 413). Top-level type: payload-too-large. Sub-error detail: Payload for 'schema' exceeds max size of {maxBytes} bytes (actual: {actualBytes} bytes) |
validation-error | Generic fallback for unexpected runtime errors during schema validation |
Property Validation Error Types​
| Error Type | Description |
|---|
invalid-property-type | Property type is not a valid JSON Schema type |
invalid-property-name | Property name format is invalid |
duplicate-property-name | Duplicate property name (case-insensitive) |
property-slug-conflicts-with-relation | Property name conflicts with an existing relation slug |
too-many-properties | Definition exceeds the maximum of 20 properties |
invalid-default-value | Default value does not match the property schema |
default-value-required | Cannot add or make property required without a default value when existing instances contain null values |
unsupported-keyword | Schema uses a JSON Schema keyword that is not supported (e.g. patternProperties) |
invalid-pattern | pattern value is not a syntactically valid regular expression |
unacceptable-pattern | pattern value is syntactically valid but uses features that are not supported, such as lookaheads or backreferences. Only linear-time regular expressions are accepted |
Property Rename Error Types​
| Error Type | Description |
|---|
incompatible-type-change | Invalid property type conversion during rename |
invalid-rename-from | renameFrom is not allowed during definition creation |
invalid-rename-from-reference | renameFrom references a non-existent property |
invalid-rename-from-value | renameFrom value has an invalid format |
rename-conflict | Target property name already exists |
Relation Error Types​
| Error Type | Description |
|---|
definition-not-found | Referenced definition does not exist for the relation |
duplicate-relation-slug | Relation slug is already used on this definition |
https://problems.tourfold.com/relation/relation-id-null | Relation has an id null |
https://problems.tourfold.com/relation/unknown-field-in-order-by | Unknown field in order by request |
https://problems.tourfold.com/relation/unknown-nested-field-in-order-by | Unknown nested field in order by request |
https://problems.tourfold.com/relation/invalid-sort-direction | Invalid sort direction |
https://problems.tourfold.com/relation/nesting-depth-exceeded | Nesting depth limit exceeded |
relation-not-found | Relation was not found |
required-relation | A required relation is missing in the associations |
location-relation-must-be-one-to-one | A relation marked with settings_type: "location" must have cardinality ONE on both sides. The offending side's actual cardinality is surfaced in data.actual. The error appears once per offending side and the pointer (#/relations/{N}/a/cardinality or .../b/cardinality) identifies which one. |
location-relation-must-target-property-location | A relation marked with settings_type: "location" must connect to the built-in location definition on one side. Returned when neither side's definition_slug is location. |
Location Error Types​
These errors come from the location built-in pre-processor when creating or updating a location instance.
| Error Type | Description |
|---|
invalid-tracking-id | tracking_id is not a syntactically valid UUID. |
tracking-id-not-found | tracking_id does not reference an existing location instance. The reference must already be persisted; pointing at another instance being created in the same batch is rejected with this type. |
geocoding-failed | Address geocoding returned no result for the supplied street / street_number / post_code / city / country. |
Association Error Types​
| Error Type | Description |
|---|
cardinality-violation-source | Source cardinality constraint violated |
cardinality-violation-target | Target cardinality constraint violated |
duplicate-association | Duplicate association for same relation and target |
object-not-found | Associated instance was not found |
Instance Validation Error Types​
These appear when instance data fails validation against the definition schema.
| Error Type | Description |
|---|
type-mismatch | Value does not match the expected type |
required-field | A required field is missing |
invalid-enum-value | Value is not one of the allowed enum values |
invalid-const-value | Value does not match the expected constant |
string-too-short | String length is below the minimum |
string-too-long | String length exceeds the maximum |
pattern-mismatch | String does not match the required pattern |
value-too-small | Numeric value is below the minimum |
value-too-large | Numeric value exceeds the maximum |
not-multiple-of | Numeric value is not a multiple of the required value |
too-few-items | Array has fewer items than allowed |
too-many-items | Array has more items than allowed |
duplicate-items | Array contains duplicate items when uniqueness is required |
invalid-format | Value does not match the required format |
too-few-properties | Object has fewer properties than required |
too-many-properties | Object has more properties than allowed |
additional-properties-not-allowed | Object contains properties not defined in the schema |
oneOf-mismatch | Value does not match exactly one of the oneOf schemas |
anyOf-mismatch | Value does not match any of the anyOf schemas |
allOf-mismatch | Value does not match all of the allOf schemas |
not-mismatch | Value matches a schema it should not |
conditional-mismatch | Value does not satisfy a conditional (if/then/else) schema |
dependent-required | A dependent required property is missing |
dependent-schema-mismatch | Value does not match a dependent schema |
validation-error | Generic validation error (fallback) |
instance-payload-too-large | data payload exceeds the configured max size (HTTP 413). Top-level type: payload-too-large. Sub-error detail: Payload for 'data' exceeds max size of {maxBytes} bytes (actual: {actualBytes} bytes) |
Custom Objects Error Example​
{
"type": "https://problems.tourfold.com/validation-failed",
"title": "Validation failed",
"detail": "Schema validation failed with 1 error(s)",
"status": 422,
"errors": [
{
"type": "default-value-required",
"title": "Default value required",
"detail": "Cannot add or make property 'priority' required without a default value because existing instances contain null values for this property",
"pointer": "#/priority"
}
]
}
Custom Objects GraphQL Errors​
These errors occur when using the Custom Objects GraphQL API endpoint.
GraphQL failures are returned in the errors array (typically with HTTP 200 OK) and do not use RFC 9457 problem payload fields.
Which errors carry a code​
Everything Tourfold rejects about a query carries a stable extensions.code — the limits below, a
malformed cursor, contradictory pagination arguments, and every rejected filter operand. Branch on that
code. The full list, with the data each one reports, is in
GraphQL errors and limits.
Only errors raised by the GraphQL engine itself, before any Tourfold code runs, have no code. Those
are document problems, and message plus locations is all there is:
| Message pattern | Meaning |
|---|
Validation error (FieldUndefined@...) ... Field ... is undefined | The field is not in your workspace's generated schema. Check the schema endpoint. |
Validation error (WrongType@...) ... not a valid SortDirection | An order_by direction other than asc or desc. |
| Validation error (WrongType@...) ... | An argument value of the wrong type for its declared input. |
| Invalid syntax ... | The document does not parse. |
Earlier versions of this page listed message patterns for filter-depth, cursor and filter-operand
failures. Those now carry stable codes and their wording has changed — match the code, not the text.
Query Validation​
| Constraint | Limit | Description |
|---|
| Query length | 10,000 characters | Maximum length of the GraphQL query string |
| Query cost | 100,000 estimated rows | Maximum rows a query may be estimated to materialise. A connection multiplies its subtree by its page size; plain fields cost 1. Exceeding it returns graphql/query-too-complex. |
| Query depth | 12 levels | Maximum nesting depth, counted in Relay levels rather than relation hops: a bare connection already costs 4, and each to-many hop adds 3. Exceeding it returns graphql/query-too-deep. |
Page size (first/last) | 100 | Larger values are silently capped. |
| Default page size | 20 (root), 10 (nested) | Applied when neither first nor last is given. The nested default is smaller because a nested connection resolves once per parent row. |
| Filter nesting depth | 4 | Maximum where recursion depth (_and / _or). Independent of query depth. |
| Order-by nesting depth | 3 | Maximum order-by nesting depth |
| JSON filter operand size | 3,000 characters | Maximum size of JSON values in filter operators |
| LIKE wildcards | 2 | Maximum number of wildcard characters in LIKE patterns |
Query cost replaced an earlier "query complexity" score of 25, which counted fields and so was
inversely correlated with actual cost — it rejected a wide table view while permitting a narrow, deeply
paginated traversal orders of magnitude more expensive. A response reports its cost under
extensions.cost whenever the request reached cost analysis — successful executions and
query-too-complex refusals — so a query can be tuned before it starts being refused. Syntax and
validation failures are caught earlier and carry no cost.
See GraphQL errors and limits for the worked cost arithmetic and how
each limit is counted.
Custom Objects GraphQL Error Example​
{
"data": null,
"errors": [
{
"message": "Validation error (WrongType@[product]) : argument 'order_by[0].price' with value 'EnumValue{name='invalid_direction'}' is not a valid 'SortDirection' - Literal value not in allowable values for enum 'SortDirection' - 'EnumValue{name='invalid_direction'}'",
"locations": [{ "line": 1, "column": 11 }],
"path": null
},
{
"message": "Validation error (FieldUndefined@[vending_machine/cpu_processor]) : Field 'cpu_processor' in type 'vending_machine' is undefined",
"locations": [{ "line": 5, "column": 9 }],
"path": null
},
{
"message": "Validation error (FieldUndefined@[vending_machine/manufacturer/founding_year]) : Field 'founding_year' in type 'manufacturer' is undefined",
"locations": [{ "line": 8, "column": 13 }],
"path": null
}
]
}
Billing Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/billing/billing-customer-missing | Billing customer missing | The tenant has no Stripe customer yet, so this billing action is not available | 422 |
https://problems.tourfold.com/billing/plan-change-in-progress | Plan change in progress | A billing plan change is already in progress for this tenant | 409 |
https://problems.tourfold.com/billing/plan-change-not-allowed | Plan change not allowed | The subscription plan cannot be changed in the current billing state | 422 |
https://problems.tourfold.com/billing/seat-cap-exceeded | Seat cap reached | The tenant has reached the maximum number of paid seats allowed by its current plan | 422 |
https://problems.tourfold.com/billing/stripe-billing-unavailable | Stripe billing unavailable | Stripe billing could not be reached or could not process the request | 503 |
https://problems.tourfold.com/billing/plan-configuration-invalid | Plan configuration invalid | The plan's Stripe configuration is incomplete or inconsistent and cannot be materialized (a server-side/config condition, not a client error). | 500 |
Signup Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/signup/email-already-verified | Email already verified | This email address has already been verified | 409 |
https://problems.tourfold.com/signup/email-not-verified | Email not verified | Verify your email before continuing with the signup flow | 409 |
https://problems.tourfold.com/signup/invalid-verification-code | Invalid verification code | The verification code provided is not valid | 422 |
https://problems.tourfold.com/signup/verification-code-expired | Verification code expired | The verification code has expired | 422 |
https://problems.tourfold.com/signup/invalid-resume-token | Invalid resume token | The resume token is not valid or has expired | 422 |
https://problems.tourfold.com/signup/subdomain-not-available | Subdomain not available | The requested subdomain is already taken | 409 |
https://problems.tourfold.com/signup/subdomain-reserved | Subdomain reserved | The requested subdomain is reserved and cannot be used | 409 |
https://problems.tourfold.com/signup/subdomain-invalid-format | Invalid subdomain format | Subdomain must use 3-16 lowercase alphanumeric characters | 422 |
https://problems.tourfold.com/signup/session-not-found | Session not found | The signup session does not exist | 404 |
https://problems.tourfold.com/signup/session-already-completed | Session already completed | The signup session has already been completed | 409 |
https://problems.tourfold.com/signup/session-not-ready | Session not ready | Complete all required steps before finishing the signup | 422 |
https://problems.tourfold.com/signup/payment-pending | Payment pending | The payment is still processing. Please wait and try again | 409 |
https://problems.tourfold.com/signup/completion-in-progress | Signup completion in progress | The signup is already being completed. Please wait and try again | 409 |
https://problems.tourfold.com/signup/payment-not-completed | Payment not completed | The payment has not completed | 409 |
https://problems.tourfold.com/signup/payment-failed | Payment failed | The payment failed. Please choose a plan and try again | 409 |
https://problems.tourfold.com/signup/email-rate-limited | Email rate limited | Too many verification requests in a short period | 429 |
https://problems.tourfold.com/signup/invalid-invite-code | Invalid invite code | The invite code provided is not valid | 422 |
https://problems.tourfold.com/signup/email-sending-failed | Email sending failed | The verification email could not be sent | 503 |
https://problems.tourfold.com/signup/tenant-creation-failed | Tenant creation failed | The platform could not create a tenant for this signup | 500 |
Capacity Errors​
| Type URI | Title | Description | HTTP Status |
|---|
https://problems.tourfold.com/capacity/not-found | Measure unit not found | Measure unit was not found | 404 |