TeamcenterKnowledge

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 ModelObject that does not apply to your call, send the NULLTAG sentinel explicitly:
    {"uid":"AAAAAAAAAAAAAA","type":"unknownType"}
    
    Never omit the key. Never send JSON null.
  • A scalar attribute can be required even when a sibling flag makes it semantically moot. RevisionRuleEntryProps requires a date attribute even when today: true is 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:

  1. It is deprecated (above).
  2. A magic field value is wrong. createDatasets returns success with NO dataset whenever toolUsed is anything other than "".
  3. The real reason is sitting in ServiceData.partialErrors and 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:

  • 214085 on Requirementsmanagement/createOrUpdate was read as "the RM service is not activated, escalate to an admin." It actually meant the AWC never uses that operation. The real one is Core-2016-09-DataManagement/createAttachAndSubmitObjects.
  • Version probes returning 214086 were read as "this server only exposes the 2006-03 SOA generation." False. The live UI uses Core-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

  1. Did it fault? Read .QName and the code, then the table above.
  2. Did it return 200 with nothing? Check deprecation and the named successor.
  3. Still nothing? Confirm the operation is on the service you think it is.
  4. Struct still rejected? Rebuild the request straight from the XSD <sequence>, NULLTAG every inapplicable required ModelObject.
  5. 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/getTypeDescriptions2 on 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.