Skills
TC Parameters Units
Skill
tc-parameters-units. Author Teamcenter parameters, parameter definitions and units. The three-tier model (definition, parameter, measure value), the AttributeTargetManagementService API that beats hand-rolled creates, the unit-of-measure system (UMS) and its CSV loader, and the traps around att0Uom, the unit picker and the current_project blocker. Use for MBSE parameters, engineering characteristics, KPIs or units of measure in TC.
The model is THREE tiers, not two
| Tier | Type | Carries |
|---|---|---|
| Definition (the dictionary term) | Att0AttributeDef / Att0AttributeDefRevision |
att0AttrType, att0Uom, LOV, default, goal, range |
| Parameter (the instance on an object) | Att0MeasurableAttribute{Dbl,Int,Str,Bool,Pnt} |
att0Uom (the "As Authored" unit, the instance carries one TOO), att0Goal/Min/Max, att0AttrDefRev, att0ThreadId (P000nnn), att0CurrentValue |
| Measurement (the actual number) | Att0MeasureValue{Dbl,...} |
att0Value, att0DateMeasured, att0SourceType |
att0CurrentValue is a REFERENCE to the latest MeasureValue, not a scalar, and
att1Value on the parameter is a pass-through. Do not conclude "no value" from
one field: follow the reference. In one live check the MeasureValue records existed
with real dates and att0Value empty, which is a genuinely different fact from
"no measurement was ever taken."
Definitions live in an Att0ParamDictionary, which is a subclass of
Folder — its members are in contents, and it is created like a folder, not
like an item. On a tier with program security, project membership gates
visibility of a dictionary's contents, not just writes: a non-member's SOA read
of contents came back empty while the Rich Client showed all 32 members to a
project member.
Owner link is the GRM relation Att0HasParamValue. Owner is not a property:
get it via expandGRMRelationsForSecondary on Att0HasParamValue. Eleven owner
types can carry parameters (Project, Package, Requirement, Block, Activity, Proxy
Port, Connector, Object Flow, Interface Block, Signal, Activity Parameter Node).
Reading parameters back the fast way
Read the relation as a plain property on the owner — one call:
getProperties(uid=<Fnd0LogicalBlockRevision>, attributes=["Att0HasParamValue"])
-> ui "P000382/A;mass" db "cUrpGP7vZ$cfED"
expandGRMRelationsForSecondary run from the block returns empty — that's
correct behavior, wrong direction: the block is the primary side of the relation,
the parameter is the secondary. Empty there does not mean "no parameters"; it
means you queried from the wrong end.
Use the first-class API, do not hand-roll
AttributeTargetManagementService exists. Two templates:
AttrTargetMgmt:createParameters,updateParameters/2,attachParameters,getParameters,getLatestDefinitions,getLatestMeasureValues,replaceParameters,replaceParameterDefinitions,deleteMeasurableAttributes,get/setAttributeComplexData.AttrTargetMgmtAW:createOrUpdateMeasurableAttribute,importParameterExcel(the supported bulk loader),mapMeasurableAttributes/2,attachMeasurableAttributes,publishParameters,setParametersDirection,removeParameters,getMeasurableAttributes2.
TargetManagement.CreateOrUpdateInput carries object_name plus
att0AttrDefRev, att0Min, att0Max, att0Goal, so att0AttrDefRev IS
settable at create time. This is the primary carrier for values, units and
definitions.
These operations are not in the SDK's WSDL kit (they are AW-side). The
Services Reference does carry the AttrTargetMgmt and AttrTargetMgmtAW
templates; look there, and capture from the AWC if the shape is unclear
(tc-capture-awc-calls).
The real createParameters envelope — do not guess it, it is NOT owningObject/paramInput at the top level
EXERCISED 2026-08-17, vm2606, AttrTargetMgmt-2020-12-AttributeTargetManagement/createParameters.
The version is confirmed 2020-12 (an older guess, 2012-10, faults 214085 service-not-
registered — that is the tell for "wrong version", not "wrong struct"). Two plausible-looking
top-level shapes ({"parameters":[...]} and {"input":[...]}, each with an owningObject/
paramInput pair) both return a hollow 200 — ok:true, empty outputs, no partialErrors,
nothing created, nothing named as wrong. That is the JSON-REST binding silently accepting an
unrecognized top-level key as "zero items", not a struct-content error, so Rule 2b's partialErrors
check does not catch it either. The read from the local Services Reference javadoc
(AttrTargetMgmt/.../_2020_12/AttributeTargetManagement.CreateParamsInput.html and
.ParameterProperties.html) gives the actual struct, and the interface page names the top-level
operation parameter inputs (plural):
{"inputs":[{
"clientId":"c1",
"parent":{"uid":"<owning object uid>","type":"<owning object type>"},
"paramProperties":[{
"clientId":"c1",
"paramInput":{"boName":"Att0MeasurableAttributeDbl",
"propertyNameValues":{"object_name":["<name>"],"att0AttrDefRev":["<defRev uid>"]},
"compoundCreateInput":{}},
"paramDirection":"unused",
"goalFiles":[]
}]
}]}
paramDirection is optional per the javadoc (values "input"/"output"/"unused") but was sent
anyway; goalFiles likewise optional, sent as []. Response confirms via createdParams[].parameter
(the new Att0MeasurableAttribute* uid) and ServiceData.updated/created naming real objects —
the owner revision gains Att0HasParamValue pointing at the new parameter, visible in the same
response. To attach a value at create time too, nest it under paramInput.compoundCreateInput
exactly as the standalone recipe earlier in this skill shows (att0CurrentValue → nested
Att0MeasureValueDbl child) — that part was already correct, only the outer inputs/parent/
paramProperties envelope was missing before this pass.
Traps around creating a definition
att0Uomis on the ITEM (Att0AttributeDef.uom_tag), NOT the revision.Unable to find a property with name Att0AttributeDefRevisionCreI/att0Uom(code 38015) fires because the unit was put on the revision create-input. The earlier conclusion that "the create API cannot set the unit at all" was wrong about the reason. ✅ EXERCISED 2026-08-14, vm2606 ased, 10/10 definitions. This prediction was right and seeding is ONE step.createAttachAndSubmitObjectswithcreateData.propertyNameValues = {"object_name":[n], "uom_tag":[<UOM uid>]}andcompoundCreateInput.revision[0].propertyNameValues = {"att0AttrType":["Double"]}. Read back, the item'suom_tagand the revision'satt0Uomboth carry the requested uid.att0AttrTypevocabulary confirmedDouble/Integer/String;Booleanstill untested. Nine definitions batched in one call all succeeded. ⚠ Verify by the db UID, never the display string. An UNBOUND unit renders aseach:000391-Integer (each)hasatt0Uomui=each, db=empty, which reads exactly like the realEach(Counting, uidQ4BAAAj1p$kOEC). It is a permanent negative control on that tier - use it.- The unit must be correct at create time. Post-hoc
uom_tagrepair is blocked:tcxml_import -bulk_loadreports "BULK LOADER IS NOT AVAILABLE" and-low_levelreports "SITE CONSOLIDATION IS NOT AVAILABLE" on a licence-limited tier. - A site can block object creation entirely for a service account. If
createAttachAndSubmitObjects,createObjectsand even a plainFolderall fail withcurrent_project(38041) plusUnable to create Business Object(214200), that is an account/session defect, not a "this type is not creatable" result. The rich client route (My Teamcenter > File > New > Other...,Ctrl+H, filter for the type) works asinfodba/dba. - The RAC create wizard clears its fields and stays open after Finish. That is a create-another affordance and it means success, not failure. Pressing Finish again makes a second object.
- Rich Client path: File > New > Other… > Parameter Definition exposes ID /
Revision / Name / Description / Application / Data Type / Unit of
Measure on the item panel. Data Type options are Value, Double, Integer,
Boolean, String, Point; the choice materializes as the class of the default
parameter value (Double →
Att0MeasurableAttributeDbl), which is why noatt0AttrTypeattribute appears in exported TcXML — it's implicit in whichAtt0MeasurableAttribute*subclass got created.
Release gates the HCL EXPORT path, not Teamcenter-native use
⚠ Scoped 2026-08-08. This section used to be headed "a definition is useless until it is RELEASED", and that over-generalised. Every measurement behind it came from the Cameo/HCL export path, and a second session read the old heading as "I cannot use my four fresh definitions yet" and stopped. They could have carried on. Say which consumer a gate belongs to.
⚠⚠ CORRECTED 2026-08-31: the heading above is TIER-DEPENDENT, and on saber2506 it is false. Do not carry "release is not required" to a new tier without testing it.
EXERCISED on saber2506 (Saber 2.0 / Pre-Int 2506, user dcproxy, group dba), authoring
a mass parameter on Fnd0LogicalBlockRevision. createParameters is pure TC-native,
no Cameo anywhere in the path, and it refused:
createParameters, definition 044805 with release_status_list EMPTY
-> 185012 "The attribute definition revision \"DFSE Mass\" is not enabled."
setReleaseStatus newReleaseStatusTypeName="Pending" -> ok, status attached, date_released set
createParameters again -> 185012 AGAIN, identical
setReleaseStatus newReleaseStatusTypeName="SKW4_ReleasedFML" -> ok
createParameters again -> ok, 11 created, 0 partialErrors
Two things this settles, and neither was predicted by the vm2606 measurement below:
- The gate applies to TC-native
createParameterson this tier, not only to the HCL export. The 185012 message is word-for-word the one the HCL export gives, which is why it reads as an export-only gate until you hit it from a raw SOA client. - "Any status attached" is NOT sufficient here.
Pendingattached cleanly, set a realdate_released, and read back on the revision, and the gate still refused. Only the site's ownSKW4_ReleasedFMLcleared it. The vm2606 note below saying Pending counts is true there and false here.
A fresh session was NOT needed: the retry after Pending was run on a brand-new login
and failed identically, so this is not session caching.
⇒ Treat the release requirement as unknown until measured on the tier you are on, and when it bites, try the site-specific released status before concluding anything else.
On vm2606, release is NOT required for TC-native parameter work. Measured live there
against a definition with release_status_list confirmed empty
(001225-MEG-MOE-01 Target custody duration, unit min):
createParameters naming att0AttrDefRev = <unreleased defRev> -> ok, created 1
saveViewModelEditAndSubmitWorkflow3 value write -> ok, 0 partialErrors
read back: att1Value=18.5 att0Goal=12 att0Min=5 att0Max=30
So a freshly created, unit-bound, unreleased definition binds, carries a value,
and reads back. Release it for lifecycle governance, not to unblock authoring.
(Test litter removed with removeParameters toDelete:true, 6 objects, and a
saved query on the test name returns 0.)
Where release genuinely does gate: the Cameo/HCL export, which fails with
Export Failed: The attribute definition revision "mass" is not enabled.
There is no att0Enabled boolean. "Enabled" there means a release status is
attached — being in a workflow is not sufficient. Measured across four
revisions, all judged by whether the HCL export accepted them:
| revision | release_status_list |
date_released |
HCL export accepts? |
|---|---|---|---|
Real |
Released FML | set | yes |
Ground Speed |
Pending | set | yes |
Double (1/K) |
(empty) — but IS in a workflow | empty | no |
| freshly created | (empty) | empty | no |
The gate is having any status attached (here "Pending" is a status name and
still carries a real date_released), not workflow membership.
The release recipe — no workflow needed
Workflow-2007-06-Workflow/setReleaseStatus (not deprecated). All three
ReleaseStatusOption attributes are required even when empty, and the schema
notes only Append is supported:
{"input":[{"operations":[{"newReleaseStatusTypeName":"Pending","operation":"Append",
"existingreleaseStatusTypeName":""}],
"objects":[{"uid":"<Att0AttributeDefRevision uid>","type":"Att0AttributeDefRevision"}]}]}
One live call took 31 definitions to ok, no partialErrors, 62 objects updated
(revisions + their items). Verified 32/32.
Read the status type name from name.db, not the display value. "Released
FML" is the ui string shown in the picker; the real type name to pass is
SKW4_ReleasedFML (site-specific naming, but the ui-vs-name distinction is
general). Passing the display string fails.
Units of measure (UMS)
TC's unit management system is new in 2406 and built on Classification. It is
administered by a CSV, not by hand-made objects: unit_definitions.csv in
<TC_DATA> (an annotated unit_definitions.xls ships as an authoring aid, ~1400
units, only a subset installed per site).
Columns map onto ISO/QUDV almost one to one: Quantity (the quantity kind, and
TC's UOM picker filters by it), Unit name, Symbol (unique), Dimensionality
(nine integers; the measured order begins Mass, Length, Time, Temperature, and
the prose docs name only eight properties for nine slots so verify against the
shipped file), System of Measurement, Base unit, Conversion multiplication factor, Conversion addition factor (offset, temperature only), Display Set.
Utilities (require the DBA group, run on the TC host):
ums_import_unit_definitionswith-createUOM(default),-updateUOM,-hideUOM,-showUOM,-allowOverwrite,-applications=<name|all>, and-dryRun, which Siemens strongly recommends. Users must re-login after.ums_mappingfor legacy-BMIDE-to-UMS migration:-analyze -report_file=is read-only and proposes matches by name and symbol into a CSV whoseIs Approvedcolumn is opt-in. States: Existing-mapped, Candidate-match, Multiple-match, Non-matching, NA. Then-map,-unmap,-create_uom.
Never alter existing conversion factors (it compromises data when converting between measurement systems), and save the CSV as UTF-8 with BOM or characters like Angstrom, superscript two and Ohm corrupt.
Store the as-authored unit, never silently convert. Display sets do the
conversion per user (UMS_Preferred_Display_Unit_Set; provided sets Metric,
Metric(SI), Non-Metric). Gotcha when reading factors: the metric base unit is the
millimetre, not the metre; non-metric is feet.
Unit-picker traps measured live
- A UOM table can be doubled up. One site returned two objects for symbol
kg(case-insensitive match):kg= "Kilograms" andKG= "KG - Kilogram", one modern UMS row and one legacy/ERP import. Any ISO binding keyed on name or symbol will hit Multiple-match. Runums_mapping -analyzefirst. - The picker's Description column can be wrong. Match on the symbol. A picker
row reading
kgdescribed itself as "MassFlowRate : Kilogram per second" whileKD3read "Mass : Kilograms". Picking by description binds the wrong unit. Symbol was unique across all 655 UOM objects on that site. - A picker row can be a LEGACY UOM object that merely displays the UMS
quantity/unit name. Creating a definition off a row labelled
DEG("Angle : Degrees") boundsymbol="DEG" unit="DEG - Degree", not the proper degree object.ums_import_unit_definitions -dryRunconfirmed all the units were already installed, so this is aums_mappingproblem, not a missing-unit problem. Do not substitute legacy codes: that silently decides which unit population is authoritative. - Filter the picker by SYMBOL, never by an assumed description.
kmandN-mwere both wrongly called blocked because the search used "Kilometers" and "Torque" while the picker holds "Length : Kilometer" (singular) and "Energy : Newton-meters". UnitOfMeasurehas noobject_name, so a generic type query returns 0 for it. ⚠ Corrected 2026-08-14: the reason is the CRITERION, not an emptyobject_string. Measured on vm2606,object_stringon a UOM reads"kg", not empty; the General... saved query matches onobject_name, which the type does not have, so it can never match. Same zero, different cause. ✅ Enumerate them with the picker's own LOV (EXERCISED 2026-08-16, vm2606, 267 units,moreValuesExist:false— provably complete, matches the 2026-08-14 count exactly, so the installed set hasn't changed between runs). ⚠ Corrected 2026-08-16: the shorthand payload previously recorded here (propertyName/lovInput.boName/filterData.numberToReturnas flat top-level members) faults 214007 (DOM parsing) — it is missing structure the XSD requires. It was never actually re-run after 2026-08-14; the fault only surfaced when a second session tried it fresh. Grounded againstCore1305LOV.xsdon the 2606 kit,Core-2013-05-LOV/getInitialLOVValues's real envelope is:
Every member above is{ "initialData": { "lov": "<NULLTAG ModelObject, required>", "lovInput": { "owningObject": "<NULLTAG>", "propertyValues": {}, "boName": "Att0AttributeDef", "operationName": "Create" }, "filterData": { "filterString": "", "maxResults": 0, "numberToReturn": 500, "sortPropertyName": "", "order": 0 }, "propertyName": "uom_tag" } }use="required"in the XSD and must be present even when empty — that's what the flat shorthand omitted. Each returned row gives symbol,Quantity : Unit name, and the uid. No site-specific saved query needed, so this works on any tier.
What's actually in the shipped unit catalog, and what isn't
Checked directly against the master unit_definitions.csv (1420 rows, not the
267-unit installed subset) on vm2606, C:\apps\PLM\tc_data\unit_definitions.csv,
via a WinRM host read, 2026-08-16:
- Samples-per-second / GSPS is not a quantity Siemens models at all — not installed, not in the master file, no Time-family row comes close. Modeling it means authoring a new quantity kind and dimensionality from scratch, not importing an existing definition. Don't assume "surely it's in the full reference, just not installed here" — checked exhaustively, it is not.
- Nanosecond and year are absent from the master file too, not just
uninstalled at this site. The Time quantity's full row set across all 1420
entries is only day/hour/minute/millisecond/second/microsecond. A site that
needs
nsoryrhas to author new rows, not just runums_import_unit_definitionsagainst what Siemens ships. - Millivolt and minute ARE both already installed (found live in the 267-row
enumeration above) — reach for those before assuming a gap. Verified end to end
as the correct-unit fix path for a voltage- or duration-scale mismatch: delete
the old parameter pair (
deleteMeasurableAttributes, confirm the full cascade — parameter + measure value + form + relation, both requirement- and verification-side), create aParameterDefinitionbound to the real unit, re-author both parameter instances against it, re-verifyatt0Uomby db uid (never the display string —eachrenders identically for bound and unbound) and the value byatt1Value.
Adding a genuinely missing unit — DERIVED, not exercised end to end
ums_import_unit_definitions.exe lives at tc_root\bin on the TC host (path and
-help output confirmed live on vm2606). Contract: -u=<user> -p=<password>|-pf=<file> -g=<group> -file=<csv> -applications=<name|all> [-createUOM] [-dryRun]. New rows follow the existing convention for their
quantity — for Time, dimensionality is "0,0,1,0,0,0,0,0,0" (matches every
existing Time row) and the conversion factor is in seconds (the existing Day row
uses an exact-seconds convention, so a Julian-year row would use 31557600).
Candidate Time_ns (factor 1e-9) and Time_year (factor 31557600) rows were
drafted against the shipped file's exact format but not run — this recipe is
DERIVED from the CLI contract and the CSV format, not proven by an actual import.
Treat it as a hypothesis until someone runs -dryRun and reads the result.
⚠ This step needs a human, not an agent. The utility takes the DBA password
as a plain CLI argument over a non-interactive WinRM session. This workspace's
credential store is DPAPI-encrypted specifically so an agent session never
resolves a plaintext secret, and there is no MCP tool wrapping this utility. A
plaintext credentials file was found sitting on the VM at C:\apps\PLM\Misc\ Startup\Usernames and Passwords.rtf during this work and was deliberately
not opened — using it would just be re-triggering the plaintext-credential
pattern this workspace already flagged and closed once, not resolving a real
blocker. Hand the CSV plus command to a human to run interactively with their
own DBA login, in two separate blocks (build the CSV, then run the import),
never chained or piped together.
-pf wants an ENCRYPTED file, not raw plaintext — attempted 2026-08-16, deferred by Chris
A raw-plaintext -pf=<file> (built via the standard two-block Get-Credential →
Out-File pattern) faults on login: Error code = 515143 (POM_invalid_account_values) / "the file failed to open, or password is empty, or decryption of password failed". That wording is the tell —
ums_import_unit_definitions tries to decrypt whatever's in the -pf file, so
raw plaintext will never work regardless of whether the password itself is
correct.
The encryption tool is C:\apps\PLM\DSP\DispatcherClient\bin\encryptPass.bat,
usage encryptPass <password> — confirmed by reading the script's own source
and by exercising its no-arg path ("Password not specified", exit 0, zero
credential material involved). On a TC_USE_KEYMANAGER=FALSE host (this one is),
it shells out to com.teamcenter.ets.util.TcDebugUtil -enc %1.
⚠ This takes the plaintext password as a bare CLI argument, not a masked
prompt. That is a materially different, worse exposure than Get-Credential
(process listing, shell history) and should not be handed to someone as an
innocuous copy-paste block — say so explicitly if you ask a human to run it.
Not resolved, real gap, not papered over: whether -enc writes a file itself
or prints the encrypted value to stdout for redirection, what extension/format
-pf= then expects to consume, and whether Teamcenter's own documented contract
for -pf (never checked — only the shipped script's behavior was read) says
anything different. This path was deferred by Chris 2026-08-16 rather than
pursued further; the CSV (Time_ns/Time_year rows, see above) is still valid
and ready whenever someone picks this back up.
The three-layer plan for getting ISO units into TC
- Units into UMS via
unit_definitions.csvandums_import_unit_definitions(plus a display set). DBA work, needs a dry run, and must precede layer 2. - Terms into a parameter dictionary (
Att0AttributeDef) withatt0Uompointing at layer-1 units, seeded viaimportParameterExcelor AW Excel Round Trip > Import. - Instances as parameters on blocks, with the as-authored unit and value, via
AttributeTargetManagementService.
The failure mode this avoids: on one live site, 170 parameters existed under only
57 distinct names, 36 of them orphaned, exactly 1 carrying a value, and 10 of 12
definitions were DATATYPE-shaped (Real, Integer, Boolean) rather than
engineering terms, so mass, power, fov and orbitAltitude all collapsed onto
one unitless definition named Real. Bind to engineering characteristics
(Mass), never to datatypes (Real).
Instance-level rebind APIs — replaceParameterDefinitions is dictionary-scoped
Check the contract before reaching for a "replace" call. AttrTargetMgmt-2506/ replaceParameterDefinitions takes a dictionary plus selectedParamDefRev →
targetParamDefRev, and its own WSDL doc says it "replaces given parameter
definitions with target parameter definitions under the parameter dictionary."
It swaps definition A for definition B across an entire dictionary — using it to
re-point one parameter off e.g. Real would rebind every parameter bound to
Real on the whole tier. New in 2506; not present in earlier WSDLs.
The instance-level operations are replaceParameters and updateParameters2
(both 2112), and attachParameters/createParameters (2012, already covered
above). updateParameters2 carries a generic paramProps name/value map, which
is the likely route for changing one parameter's binding. Unverified — this has
not been tested end-to-end; treat as a hypothesis, not a proven recipe, until
someone runs it and reads the result back.
The Cameo / HCL connector contract
Relevant when parameters are authored in Cameo Systems Modeler and pushed into TC via the HCL Cameo-Teamcenter connector:
- An unstamped SysML value property aborts the entire export. It's the
stereotype being absent that kills it, not an empty value — an empty
Measurementstereotype does not abort the export (negative control: item 041273 "Signals and Interfaces" pushed fine with an empty Measurement). - Cameo cannot assign a definition.
TC_Parameter_Stereotype.ObjectIdandatt0AttrDefRevare both mapped TcToTool only in the connector. Proven end to end: repointing a value property'sObjectIdat a released non-default definition (Ground Speed, mph) and re-pushing updated the value to 55 but leftatt0AttrDefRev=040749/-/Realandatt0Uomempty —ObjectIdis read and validated against the release-status gate at push time, then discarded. The definition binding has to be established TC-side, not from Cameo.- Beware the confounded version of this test: stamping
ObjectId = Realand gettingRealback proves nothing, sinceRealis the default definition anyway.
- Beware the confounded version of this test: stamping
- A failed HCL export is not atomic. It leaves blocks created without their parameters, and a retry creates a second full set rather than resuming cleanly.
- UX trap: neither Put Model nor Synchronize pushes local edits once an item exists — both pull from the server and discard local changes. Check-In is the actual push action. This has burned people who edited locally, hit Synchronize expecting a push, and silently lost their edit.
- Unverified: whether a genuinely new, never-synced value property behaves
differently from an update on the
ObjectIdquestion above — only the update-path behavior has been measured.
★★ Never create the Att0MeasureValue* as a standalone, disconnected object
Measured 2026-08-16, vm2606: creating an Att0MeasureValueDbl via its own
separate createAttachAndSubmitObjects call, then trying to retroactively point
a parameter's att0CurrentValue at it (via the proxy write, or setProperties),
silently no-ops both ways — HTTP 200, no fault, but att0CurrentValue stays
empty on re-read. Root cause: att0CurrentValue (and its sibling
att0Measurement) are not writable scalar/reference fields at all — they're
read-only, computed from actual containment structure. There is nothing for a
retroactive write to attach to when the value object was created independently.
The tell that confirms this: sending att0CurrentValue as a plain scalar in
createParameters faults 515029 "invalid for property Value", not 38015 "unable to find property" — the property is real and recognized, it just wants
a structured/nested value, not a bare number.
The fix is to create the measure value as a compound CHILD of the parameter,
in the SAME createParameters call, never as a separate object:
"paramInput": {"boName": "Att0MeasurableAttributeDbl",
"propertyNameValues": {"object_name": [...], "att0AttrDefRev": ["<defRev uid>"]},
"compoundCreateInput": {"att0CurrentValue": [{"boName": "Att0MeasureValueDbl",
"propertyNameValues": {"att0Value": ["<value>"]}, "compoundCreateInput": {}}]}}
This is not a contradiction of the saveViewModelEditAndSubmitWorkflow3 proxy
write documented elsewhere in this skill (that recipe also works, and is proven
across a dozen+ parameters in this workspace's history) — the proxy write
creates AND links the value in one committed step too. The failure mode is
specifically a THIRD pattern: creating the value object first, disconnected,
then trying to associate it after the fact. Don't do that.
Updating an EXISTING parameter's value — updateParameters/2 don't work as documented; the proxy write does
Measured 2026-08-16, vm2606: AttrTargetMgmt-2020-12-AttributeTargetManagement/ updateParameters faults 214022 on every non-empty parameters entry, even
reduced to a bare {clientId}. Its 2020-12 v2 sibling requires an undocumented
paramDirection/goalTableInput not present in the v1 XSD as read — the v1
struct appears incomplete as documented on this tier, not just picky about
shape. Don't sink time re-deriving the payload; fall back to the already-proven
Internal-AWS2-2025-06-DataManagement/saveViewModelEditAndSubmitWorkflow3 proxy
write used elsewhere in this skill for value writes.
One sharp trap in that fallback for an UPDATE (as opposed to the first-ever
value write on a fresh parameter): srcObjLsd must be the target
Att0MeasureValue object's OWN last_mod_date, not its parent parameter's.
Using the parameter's lsd instead produces fault 141023 with no further detail
pointing at the real cause. Read the measure value's own last_mod_date
immediately before writing, same discipline as Core-2010-09-DataManagement/ setProperties's PropInfo.timestamp requirement elsewhere in this skill.
Error codes worth indexing
| code | means |
|---|---|
38015 |
property not on that create-input — often you're on the revision when the property belongs to the item (see att0Uom above) |
38041 current_project |
the session has no valid project; site has program security on. Narrower than it looks: setReleaseStatus succeeds fine once the user is a project member, even when other creates still fail on this code |
101019 / 101020 |
Items only creatable in Program context / no current Program set |
71061 |
no access — the classic post--dryRun surprise (a clean dry run validates input, not access) |
Related skills
tc-object-authoring, tc-classification-bulkload, tc-capture-awc-calls,
tc-query-discovery.
Generated from skills/tc-parameters-units/SKILL.md in the tc-automation-skills library, which is the canonical copy and also serves as the agent skill set for Teamcenter work.