Skills
TC SOA Payload Shapes
Skill
tc-soa-payload-shapes. Build a Teamcenter SOA request that actually works. The full-struct rule, the NULLTAG sentinel, what each fault code (214022, 214085, 214086, 38015, 38041, 101019, 515110) really means, and the single most expensive failure mode in TC automation: a deprecated operation that returns 200 OK with an empty result and no error, forever. Use when a call faults, or returns success with nothing in it.
Most time lost in Teamcenter automation is lost here: to a call that looks right, returns 200, and does nothing. This skill is the decision tree.
Rule 1: the full-struct rule
Teamcenter's SOA schema is a strict XSD <sequence>. An <xsd:element> with no
minOccurs attribute defaults to minOccurs="1", which is REQUIRED. Same for
<xsd:attribute use="required">.
Consequences:
- Missing struct members fault
214022 "JSON parsing". When a TC operation faults 214022, your struct is missing members, not carrying wrong values. - For a required member of type
ModelObjectthat does not apply to your call, send the NULLTAG sentinel explicitly:
Never omit the key. Never send JSON{"uid":"AAAAAAAAAAAAAA","type":"unknownType"}null. - A scalar attribute can be required even when a sibling flag makes it
semantically moot.
RevisionRuleEntryPropsrequires adateattribute even whentoday: trueis set. - Do not send an empty array for a field the XSD annotates as a hashmap
(
xjb4c-hashmap). That is its own JSON-shape mismatch. Omit the field entirely if you have nothing to put in it.
createItems is the canonical example: always send
container: {"uid":"AAAAAAAAAAAAAA","type":"unknownType"}, relationType: "",
and each property entry complete including revId and uom.
Get the required member list mechanically
Do not guess. This repo ships a lookup that reads the shipped XSDs:
python scripts/soa_lookup.py createOrReConfigureBOMWindows
It prints the route, the deprecation status, and every member flagged
REQUIRED/optional with the NULLTAG hint attached, recursing into nested structs
across imported schemas. See tc-soa-docs-navigation for how it works.
Caveat worth knowing: the JSON REST binding tolerates some omissions the XSD marks
required (createRelations works in practice without userData). Treat the XSD as
the safe upper bound to fall back to when a call is faulting, not as a minimum you
must always meet.
Rule 2: a deprecated operation is a silent no-op, not an error
This is the single most expensive failure mode in Teamcenter automation.
Cad-2007-01-StructureManagement/createBOMWindows has been deprecated since
Teamcenter 12.2. On TC 2506 it still accepts a well-formed request and returns
200 OK with output: [], every time, regardless of body correctness. A whole
night was spent "correcting" the payload and concluding the web tier could not
read BOM structure at all. It could. The operation was dead.
When a SOA call returns 200 with an empty or no-op result and no error, check the deprecation table before concluding anything is broken server-side.
python scripts/soa_lookup.py <operationName> # flags deprecation + successor
data/soa_deprecations.json holds 174 deprecated operation names extracted from
the local Services Reference, 92 with an explicitly named successor. Two known,
already-costly entries:
| Dead operation | Successor | Deprecated since |
|---|---|---|
Cad-2007-01-StructureManagement/createBOMWindows |
Cad-2019-06-StructureManagement/createOrReConfigureBOMWindows |
TC 12.2 |
Bom-2008-06-StructureManagement/addOrUpdateChildrenToParentLine |
Bom-2025-06-StructureManagement/addOrUpdateChildrenToParentLine |
TC 2506 |
The second one explains the long-standing "BOM occurrence child-add parses but silently adds nothing" wall. It is the same deprecation pattern, not a mystery.
Counter-example that keeps this honest: Query-2006-03-SavedQuery/executeSavedQuery
is marked deprecated in favour of executeSavedQueries, yet the singular is the
one that works reliably and the plural rejected every shape tried. Deprecated
does not always mean non-functional. Deprecation is a lead to check, not a
verdict; a 200-with-empty-result is what turns it into a diagnosis.
Rule 2b: a hollow 200 can also be a swallowed partial error
There are three ways a Teamcenter call succeeds and does nothing:
- It is deprecated (above).
- A magic field value is wrong.
createDatasetsreturns success with NO dataset whenevertoolUsedis anything other than"". - The real reason is sitting in
ServiceData.partialErrorsand your client never read it.
Case 3 cost an overnight run and produced a confident, wrong conclusion that
"native Schedule Manager is dead over REST." createSchedule returned 200 with
empty output; the partial error said
code 230305 - The preference "SiteTimeZone" is required to be set for the Schedule Manager application. One unset site preference, not a transport problem
and not a payload problem. The tell was that the AWC's own Create button also
created nothing.
Surface ServiceData.partialErrors in every error path. A client that only
checks .QName is blind to the most informative failures TC produces.
Rule 2c: setProperties has TWO versions and the old one is a silent no-op
Measured on TC 2606, three times before it was believed:
Core-2007-01-DataManagement/setProperties returns 200 with
updated: ["BOM::96704"], a UserSession, and changes nothing on the target
object. No fault, no partial error. A read-back on a fresh session shows the
property untouched. It looks exactly like a successful write.
Core-2010-09-DataManagement/setProperties works, and the reason the obvious
attempt at it fails is a required member that is easy to miss:
{"info":[{"object":{"uid":"<uid>","type":"<Type>"},
"vecNameVal":[{"name":"<prop>","values":["<value>"]}],
"timestamp":"2026-08-07T15:31:05-05:00"}],
"options":[]}
PropInfo.timestamp is required ("Timestamp of the object when object was
exported to clients"). Omit it and you get 214022, which per Rule 1 reads as a
missing struct member and is exactly that. Pass the target's own last_mod_date
dbValue, read immediately beforehand.
A successful write names the REAL objects in updated (the revision and its
item), not a UserSession. That contrast is the cheapest tell that the call did
something.
Rule 3: the fault codes carry real signal, but never prove impossibility
| Code | Real meaning | What to do |
|---|---|---|
214022 JSON parsing |
Live operation, struct is missing members | Add the missing members, NULLTAG the inapplicable ModelObjects |
214086 |
Wrong route: bad service/version/domain combination | Look up the real owning service, do not conclude the release is version-pruned |
214085 |
Service not registered under that name | You are calling the wrong service entirely; keep hunting |
214200 + 38041 current_project |
Session has no valid current_project bound |
Account/session defect, not a type or permission problem. See below |
38015 "Unable to find a property with name X/y" |
The property is not on that create-input | Often it lives on the item, not the revision (att0Uom is on Att0AttributeDef, not the revision) |
101019 "can only be created in context of Program" + 101020 |
Site policy requires a program/project context | getTCSessionInfo; if project/workContext are AAAAAAAAAAAAAA the account needs project membership |
515110 "The instance is referenced" |
The object is the secondary side of a relation | Just retry deleteObjects on the leftovers; cascades free each other |
51007 on delete |
The object is inside a structure | Remove the occurrence first, then delete the freed item |
9037 on a dataset type |
That named-reference type is broken on this BMIDE | Use another (Image instead of JPEG) |
A fault code is a hint to keep hunting for the real call. It is never proof a capability is impossible. Two conclusions drawn from fault codes were later retracted as flatly wrong:
214085onRequirementsmanagement/createOrUpdatewas read as "the RM service is not activated, escalate to an admin." It actually meant the AWC never uses that operation. The real one isCore-2016-09-DataManagement/createAttachAndSubmitObjects.- Version probes returning
214086were read as "this server only exposes the 2006-03 SOA generation." False. The live UI usesCore-2016-09,Core-2015-10,Internal-AWS2-2024-12,Internal-ActiveWorkspaceBom-2025-06, and more.
If the Active Workspace UI can do it, the call exists. Capture it rather than
concluding it is impossible: see tc-capture-awc-calls.
Rule 4: a wrong service-class guess looks exactly like a broken feature
Core-2008-06-DataManagement/getTypeDescriptions2 returns a generic
InternalServerException for every type name including definitely-real ones,
because that operation is not on DataManagement at all. It is on
Core-2015-10-Session/getTypeDescriptions2. One index lookup turned a dead end
into a working call.
python scripts/soa_lookup.py getTypeDescriptions2
python scripts/soa_lookup.py --grep typedescription
Order of diagnosis
- Did it fault? Read
.QNameand the code, then the table above. - Did it return 200 with nothing? Check deprecation and the named successor.
- Still nothing? Confirm the operation is on the service you think it is.
- Struct still rejected? Rebuild the request straight from the XSD
<sequence>, NULLTAG every inapplicable requiredModelObject. - Only then consider that the capability might be genuinely absent from this
deployment, and prove that with a type-existence check
(
Core-2015-10-Session/getTypeDescriptions2on the module's core type) rather than with a fault code.
Related skills
tc-soa-docs-navigation, tc-capture-awc-calls, tc-soa-session.
Generated from skills/tc-soa-payload-shapes/SKILL.md in the tc-automation-skills library, which is the canonical copy and also serves as the agent skill set for Teamcenter work.