Skip to main content

Troubleshooting

Start from what you are seeing, not from which API you are using.

The Agility API has a particular failure signature worth understanding up front: many of its traps return 200 OK. A mistyped parameter, an unencoded character or a missing flag will frequently produce a well-formed, successful-looking response that is quietly wrong, rather than an error you can catch. Most of this page is about those.

For more information, see Error handling.

My Request Succeeded but the Data Is Wrong​

The largest and most dangerous category.

SymptomCauseWhere to look
History query returns current values, not values at that moment# was not percent-encoded. Everything after an unencoded # is treated as a URL fragment and never leaves your client — the server answers a different question than you asked, successfullyAttribute paths
where, sort, page or find appear to be ignoredOn a single-asset Data URL such as /Data/Story/1234 these are accepted and silently dropped. On /Hist/... they apply. with applies everywhereQuery grammar
Wrong page of results, or pages that overlappage=<size>,<start> — size comes first, the opposite of most APIs. page=0,50 is a zero-size page, not "the first 50"Sort and paging
Paging repeats or skips assets between pagesPaging is applied after sorting, so an unsorted list has no stable order to page throughSort and paging
total is missing from a paged responseA paged response only carries total when the server computed it. Whether it does depends on the per-instance ApiDefaultNeedTotal setting — send needTotal=true explicitlySort and paging
You get XML when you expected JSONOmitting Accept gets you XML. Accept is also honoured as a query-string parameter, not only as a headerHTTP headers
A relation update returned 200 but nothing changedact was probably on the Relation element; it belongs on the Asset value element inside it. The misplaced form is accepted silentlyREST-1 writing data
An operation returned 200 but the asset did not transitionSome redundant operations succeed and write a new moment without changing state — 200 means accepted, not transitionedREST-1 operations
Response contains attributes you never selectedSelecting any relation attribute additionally returns up to three conditional attributes — commonly just its Name. This is implicit and cannot be turned offQuery grammar
Response is far larger than expectedOmitting sel does not return "nothing" — it returns a per-type basic attribute set. Combined with no default page size, an unbounded request can try to return your whole instanceQuery grammar
Removing a tag removes nothingThe payload shape for remove is removeFrom plus field. A previously published example showed the merge shape insteadRemove a tag
History looks like it is missing versionsMoment numbers are instance-wide, not per-asset — they are not a contiguous per-asset sequenceMoments and history
Localized strings come back untranslatedAn unmatched tag echoes back as a trimmed literal of the tag itself, so a typo is indistinguishable from an untranslated termTag resolution
?noloc looks like it worked but changed nothing?noloc does not work against Agility. It is a sample-application feature; appended to a loc-2.v1 URL it is parsed as a tag and echoed straight backnoloc

I Got a Success Response but Nothing Happened​

SymptomCauseWhere to look
Bulk request returns 200 but assets are unchangedA 200 means the request was processed, not that every command succeeded. Always check commandFailures.countBulk errors
A bulk command matches nothing, silentlyIsDeleted: true is required to match deleted assets even when from is an explicit OID token. Without it the command matches nothing and reports no errorBulk queries
Only one asset is affected when several matchedSubquery cardinality differs by position: in a relation update every match is used; in an operation's args only the first isRelation updates · Operations
Update fails with ClosedAssetCannotEditExistingValuesClosed assets accept only backfill: attributes with no value can be filled in, existing values cannot be changed. Reactivate the asset to edit itOperations
Status update fails with PrimaryWorkitemCannotHaveInvalidStatusThe asset's team uses a Team Process, which restricts which StoryStatus values its primary workitems may enter. Use a status from the team's set (statuses whose Team relation points at that team)Workflows and status
Webhook created successfully but never authenticatesThe authorizationHeader key was misspelled. Unknown keys are ignored, so the subscription is created, delivers with no Authorization header, the receiver 401s, that counts as a delivery failure, and the subscription is eventually auto-disabled. Tell-tale: hasAuthorizationHeader comes back falseCreate a subscription
Webhook update lost other fieldsUpdate replaces the whole subscription; send the complete object, not just the changed fieldUpdate a subscription
Terminology change is not visible to clientsThe loc-2.v1 ETag can go stale and serve 304 with outdated text until the application restartsHot reload

My Request Fails​

SymptomCauseWhere to look
Invalid SEL parameter, Invalid WHERE parameter, Invalid PAGE parameterMalformed query-string grammar. These are the literal wire strings — useful for diagnosis, but do not match on them in codeQuery grammar · Status codes
Querying a relation attribute fails on an abstract typeA downcast is required: Workitems:Story.Category, not Workitems.Category. Applies to Workitem, BaseAsset and Scope relationsAttribute paths
filter= is rejected on rest-1.v1There is no filter query parameter on rest-1.v1 — where takes the full filter language. On query.v1 the same two names mean different thingsFilter expressions
Activity stream request 400s on a valid-looking verbVerb parsing is case-sensitive, and one wrong-cased verb fails the whole request. direction is case-insensitiveActivity stream
Bulk request returns a hard 500A missing request body produces a 500 rather than a 400Request format
A large bulk request times out on the clientThe server enforces no processing time limit and keeps running after your client gives up. Each command is its own transaction, so committed commands stay committed — there is no rollback or cancel. Re-query to find the actual state; never blindly resubmit the original payloadProcessing model
Requests 404 after a URL changeDo not drop version suffixes — the -2 in loc-2.v1 is significantBase URL
A malformed query string produces no error at allNot every bad query string is rejected; some are accepted and ignoredStatus codes

It Behaves Differently on Another Instance​

Behaviour that depends on deployment or configuration rather than on the API. Code that works against one Agility instance can fail against another with no change on your side.

  • needTotal defaults per instance, from the ApiDefaultNeedTotal setting — so a client that drives a pager off total can work in one place and break in another. See Sort and paging.
  • stackTrace appears in error responses only on development builds, which are internal to Digital.ai. Customer deployments — hosted and on-premise alike — run release builds, which never include stack traces or exception detail in API responses, and no setting can enable them. An example payload captured on an internal development instance may show the field; code must not expect it. See Bulk errors.
  • Asset type and attribute names vary with the methodology chosen at installation, and can be overridden by localization. Discover them from meta.v1 rather than hardcoding them. See Meta API and Terminology.
  • Custom fields are never in the default attribute set and must be selected explicitly.

Something Changed That I Did Not Expect​

  • POST api/webhook/delete with no id deletes every subscription in the instance, with no filtering by member. See Delete a subscription.
  • Tag merge and tag remove have no undo. See Merge and Remove.
  • Bulk failures cascade. A failure on a parent asset fails its dependents in the same request. Use preview mode to validate before writing, and see Bulk errors for how to reissue only the failed subset.

Still Stuck​

If you hit something that is not here, it is worth writing down. Undocumented behaviour that costs someone an afternoon is exactly what this page is for.