TeamcenterKnowledge

Skills

TC Bmide Project Validation

Skill tc-bmide-project-validation. Make a hand-authored BMIDE template project that BOTH the packaging utility and the BMIDE client accept. Covers the requirements neither tool documents, the two that contradict each other, the one that cannot live in the project at all, what breaks when you split a template, and the error messages that name the stage that noticed rather than the thing that is wrong. Ships verify-bmide-project.ps1, which checks all of them against any project. Use before running bmide_generate_package.bat, before loading a project into the BMIDE client, and for any "failed to load correctly" or "Unable to update the manifest file" investigation.

Derived on Teamcenter 2606 (vm2606), 2026-08-10 into 08-11, across two independently authored templates, dss4decisionmgmt and xc4programreporting. Both package and both load in the client. Neither is safely deployed: the first crashed every tcserver on the tier and was reverted, see the deploy section below.

The one thing to understand first

Two different tools judge a BMIDE project and they check different things.

Both routes produce identical payloads. Compared entry by entry on name + uncompressed size + CRC32 across _template.zip, _install.zip and _icons.zip: zero differing entries. Only container metadata differs (platform token, folder naming, derived .checksum, machine-stamped client_<name>.properties, zip container bytes).

A filename-and-hash comparison of two kits is NOT evidence of equivalence, in either direction. It was used here to claim equivalence, then to claim non-equivalence, and it never supported either. CRC32 over zip entries is the test that does.

⛔⛔ A retracted claim worth keeping visible: this skill briefly said "do not deploy the headless output, a named colleague has evidence it is not equivalent." That colleague had no such evidence and had never said it. It was a fabricated blocker attributed to a real person, and it was persuasive exactly because it sounded careful and cited a source. Before a caveat becomes a blocker in a shared document, check it with the person you are citing.

bmide_generate_package.bat the BMIDE client
runs headless, tc_root\bin\ GUI, tc_root\bmide\client\bmide.bat
catches XSD faults the client loads happily model errors the packager never sees
edits your source never silently, on load
needs install\dc_contributions, feature_<name>.xml, content directly under install\ ProjectInfo.xml, Functionality declarations, storage classes, a 4-to-9 prefix, workspace registration
ignores everything in the client column everything in its own column

★★ A fix checked against one in isolation can break the other. Declaring a missing storage class satisfied the client and then broke the packager, because the obvious name for it was 30 characters and a POM class caps at 27. Neither tool alone can validate a model. Run both, every time.

Run the checker

powershell -NoProfile -ExecutionPolicy Bypass -File verify-bmide-project.ps1 -ProjectRoot <path> -WorkspaceRoot <ws>

<ws> is tc_root\bmide\workspace\<version> (e.g. 2606000.0.0). Omit it and the workspace section says so loudly rather than skipping silently.

Exit 0 clean, 1 findings, 2 could not run. 2 is deliberately distinct: a check that could not run must never read as a check that passed.

The requirements

Packager side

  1. **install\dc_contributions\**, not packaging\. The Siemens decision_support reference tree carries it under packaging\ only, which is a fair read of that tree and wrong for the utility. Keep one copy.

  2. RETRACTED. There is no skeleton-directory requirement. This said templates, operations, services and workflows must exist or you get Cannot read the array length because "<local7>" is null. That is false.

    Measured two ways, independently, after the claim's own author retracted it: a project created by the 2606 BMIDE client contains exactly .settings, extensions, icons, install and none of the four; and deleting all four from a working project produces an identical kit, exit 0.

    The real fix for that NPE was adding install/dc_contributions (rule 1). Two things changed in one pass and the wrong one was credited.

    ⚠⚠ This is the failure mode this skill should be most careful about. The claim reached here from a colleague's README, was written up as an enforced check, and would have had every reader create four pointless directories. A wrong rule in a shared skill is worse than a wrong note: notes get doubted, checks get obeyed. Re-measure an inherited claim before enforcing it, and when the source retracts one, re-measure the retraction too rather than just flipping the bit.

  3. install\tem_contributions\feature_<name>.xml is a required input the utility reads, not something it emits. Absent, it throws a FileNotFoundException naming the exact path. Model it on a real installed template at tc_root\install\install\modules\feature_*.xml. Its absence at the directory level is reported as Unable to update the manifest file with new versions, which has nothing to do with a manifest.

  4. -dependencyTemplateFolder wants a FLAT folder of *_dependency.xml: tc_root\bmide\templates or tc_data\model. Not tc_root\install, which is nested and produces a FileNotFoundException naming a template that is in fact installed.

4a. ★★ The packager wraps everything under install/ into install/<template>/. So project content placed at install/<template>/postinstall/ ships at install/<template>/<template>/postinstall/, and every ${Teamcenter_root_path}/install/<template>/... path in package.xml misses by one level.

Put project content directly under install/: install/postinstall/, install/data/. The wrap then produces exactly what package.xml expects.

⚠ With failonerror="false" this is invisible: postDatabaseUpdate reports Success and installs nothing. With failonerror="true" it at least fails loudly. Verify it by reading the entry list of the built <name>_install.zip, never by looking at the project layout: the layout is what deceives you.

4b. An id may not be both a packageId and an appId. Deployment Center refuses to scan the media. Measured on the shipped tc2606_wntx64 kit: 378 packageIds, 462 appIds, intersection 0, with controls both ways (activeworkspacebom package-only, cm app-only), and 8 of 8 shipped fnd0_dataModelArtifact packages carry no same-named application_registry config.

★★ This constrains IDS, not artefact kinds. A package may ship an application_registry entry under a DIFFERENT id, and may declare multiple artifacts. The only rule is that no single id appears in both namespaces.

Corrected 2026-08-12. This used to end "A data-model kit belongs in the package namespace: ship no application_registry entry", which reads as a rule about what a package may CARRY. Another session quoted it into a package descriptor as grounds that a combined data-model-plus-AWC package might be impossible, and filed it as an open roadmap question. Nothing was failing. The sentence was bolded, specific, and sat under real intersection-zero measurements, which is exactly what made it persuasive: see the unchecked-caveat rule in the workspace CLAUDE.md. The measurement was always about a collision; the prohibition was never measured.

4c. ★★ bmide_generate_package.bat does NOT purge its output directory, and reports four of four steps Success while re-shipping whatever the previous run left there. A stale dc_contributions/application_registry/ survived into a new kit and would have re-shipped a defect that had just been fixed. Build into a cleared directory, and check the kit contents, not the step summary.

4d. It resolves its classpath from %FOSS_REPOSITORY_HOME%, %TC_BIN%, %TC_JAVA_HOME%. In a bare WinRM cmd it dies with ClassNotFoundException: PackageProjectMain, which reads like a broken install. Source tc_root\tc_menu\tc_<Env>_Env.bat first, in the same process.

Client side

4e. ★★ The prefix must use a digit 4 through 9. The client refuses Xc0: "Third party solution providers should use ... the prefix; Customers should use digits 4 through 9 in the prefix." It is validated in the Properties dialog, so a non-compliant prefix blocks the load, not the build, and fixing it means renaming every type and attribute that carries the prefix.

4f. Awp0Search* are TYPE constants, not property constants. Declared as TcPropertyConstantAttach with a propertyName the client rejects each one as Undefined constant name; aws2_template.xml declares them as TcTypeConstantAttach with typeName only. ⚠ This does not reconcile with the runtime SOA read, where getPropertyConstantValues returns per-property values that discriminate correctly. Unexplained, and recorded as unexplained.

4g. LOV{::} is not a valid localization id form. The client reports The value ... of attribute "id" is invalid, and it appears in no shipped template. LOVValue{::} and LOVValueDescription{::} are valid.

  1. ProjectInfo.xml, all ~53 keys. Copy from a project the client itself created (File > New), not from another repo. A minimal ProjectInfo passes the packager and fails the client, which validates the build fields and refuses its own Properties dialog when they are empty. Project-specific: Codegen.Namespace (equals the template name), ExternalBuild.BasePath.win64 (where the project sits on the build host), SoaExternalBuild.BundleVersion. ⚠ isAutoGeneratedDescriptions must be exactly "true", or BMIDE re-migrates the project on every load, reporting "None found" each time, forever.
  2. .settings\org.eclipse.core.resources.prefs with encoding/<project>=UTF-8.
  3. Functionality declared set must cover the referenced set. Every functionality="X" attribute needs a matching <Functionality name="X" .../>. The client emits one Undefined Functionality error per reference; the packager builds a valid kit without it.
  4. formStorageClassName must name a declared TcClass, or the client refuses with the storage Class ... does not exist.
  5. Template displayName must end in a letter or digit. A trailing ) is rejected outright.
  6. Workspace registration. See below. This one is not project content.

★★ If you split a template, two things do not follow the types

Splitting a large model into cascading templates is the right response to a deploy you cannot bisect. Two identity-shaped things break when you do it, and the packager builds a clean kit through both.

1. The <Functionality> declaration does not follow the types that reference it. A template declares one <Functionality> element, and every TcStandardType names it via functionality="...". That element references no type, so a split partitioned on types leaves it in whichever partition it landed in, and every type elsewhere now points at a functionality its own template does not declare.

Measured on a 105-type model cut into four: 27, 28 and 29 dangling references in layers 2, 3 and 4. The client emits one Undefined Functionality named "<name>" per reference. bmide_generate_package.bat reports four of four steps Success, and all four kits packaged before anyone noticed.

Fix: each template declares its own functionality and repoints its own types. Declaring the same functionality name in several templates is a different bet and was not tested.

2. A rename renames names, not identities. Renaming a project renames files and ids and leaves every guid="..." untouched, so four Deployment Center packages shipped claiming one guid. DC keys on the guid, not the name, so four packages with one guid are not four packages.

Both are checked by verify-bmide-project.ps1. Both were found by running it on kits that had already packaged cleanly.

★★★ The requirement that cannot live in the project

The client resolves foundation_template.xml from an Eclipse per-project persistent property, written at import time:

<ws>\.metadata\.plugins\org.eclipse.core.resources\.projects\<name>\.indexes\properties.index
    TEAMCENTER_MODEL_FOLDER
    #C:\apps\PLM\tc_root\bmide\templates
AbstractFileRepositoryServiceBroker.initializeServices
    project.getPersistentProperty(new QualifiedName("", "TEAMCENTER_MODEL_FOLDER"))
AbstractFileRepositoryProjectImportWizard.persistProperties     // writes it at IMPORT

Absent, the client reports:

File Loading Error: Cannot find file "foundation_template.xml" in "null"

and every class in the model cascades off it: 1,264 errors from one missing property in one case, 155 in another.

Fixes, either one:

  • Import the project (the wizard writes the property). Opening is not importing.
  • Project Properties > Teamcenter > BMIDE > Dependent templates directory = the flat templates folder, then tick the templates matching your <include> set. The directory must contain master.xml.

⚠⚠ ExternalBuild.Templates.Home.win64 in ProjectInfo.xml is NOT this mechanism. It is present and correct in projects that fail exactly this way. Do not use it to satisfy yourself the templates directory is configured. That claim cost two sessions several hours.

Replacing a project directory wholesale destroys the registration. Sync file-by-file. A project that loaded yesterday will fail this way today if its directory was deleted and recreated.

Name caps: 27 and 32, and the four you do not see

what cap
POM class (TcClass/@className, formStorageClassName) 27
type name (typeName, artifactName) 32

★ Teamcenter derives <base>CreI, <base>SvAI, <base>RevI, so a base type has four fewer characters of room than it looks like. The error then names the derived type, which may appear nowhere in your source, so you go looking for a string you never wrote. Check headroom, not length, and report the base to shorten.

This is why ...RevMasterS rather than ...RevisionMasterS is load-bearing and not style.

The errors name the stage that noticed, not the fault

message actual cause
Unable to update the manifest file with new versions install\tem_contributions\ missing
Cannot read the array length because "<local7>" is null a File.listFiles() on a directory that is not there. Cause unidentified: it was blamed on missing skeleton directories and that was disproved (requirement 2). install\dc_contributions fixed it in the one case measured, but two things changed in that pass
Cannot find file "foundation_template.xml" in "null" no workspace registration
The system cannot find the file specified + a path genuinely that path
the utility's full usage text any failure, not an argument error

★ Watch error quality improve as causes are removed: unnamed manifest failure, then an NPE naming nothing, then a path that names itself, then success. The most useless message came second, not first, so "the error got worse" was progress.

Count distinct FIRST errors, never the total. 1,264 and 155 were both one root cause. Diagnose from the log, not the console: the console showed the utility's usage text, which reads exactly like an argument error, while the log showed the arguments had arrived correctly.

Provenance rules learned the expensive way

  • A client-created empty project beats every other reference. It is the only artefact in this exercise that was unambiguously right.
  • A Siemens reference tree is authoritative for STRUCTURE, not for VALUES. A 2512-era snapshot had a different media-file shape and no feature_<name>.xml at all.
  • Installed form is not project form. A census of all three installed template media files said rtm_type=Major, three of three, whole population. A project carries Main. ★ Counting the entire population of the wrong artefact is still the wrong answer, and a complete census is not a control for having censused the wrong thing.
  • Two version-looking fields, opposite answers: SoaExternalBuild.BundleVersion is 2606.0.0 while currentTemplateVersion stays 2512.0_0 on the same 2606 tier. Do not make them agree.
  • client_<name>.properties is machine-specific (client_id embeds the hostname). The packager writes it on every successful build, so any built tree carries one. Never author, commit, or copy it between machines.

★★ Test the checker, not just the project

Every check in verify-bmide-project.ps1 has been run against known-bad input, and that found four bugs in the checker itself, all of which reported success:

  • a release-token test written as a calendar-year regex (^20\d\d), which silently passed 2606, the exact value it existed to catch
  • a missing-element check that crashed under Set-StrictMode and printed no summary at all, so the run produced neither a pass nor a finding
  • an em-dash check that matched its own literal
  • an index parser that read the first path in the file rather than the one following the key, so it failed a known-good project

None were visible by reading the code.

A checker is not a checker until it has been run against known-bad input. A passing check with the wrong threshold is indistinguishable from a passing check with the right one, until something crosses the gap between them.

Free controls on any Teamcenter install: point the workspace check at a client-created project (should pass) and at a name never imported (should report not registered, which is a different outcome from misconfigured).

⛔ Deploying a template can take the tier down, and the kit will look fine

Measured on TC2606, 2026-08-11. A 105-type template deployed cleanly through Deployment Center (57 of 57 tasks Success, types verified present by getTypeDescriptions2 with real and fake controls) and then crashed every tcserver:

13x  "908: SM array to free is not a valid unpacked array"   (ScopedPtr.cxx)
     FATAL 0xC0000005 STATUS_ACCESS_VIOLATION
     each tcserver dying ~1s after "Applying Object Property Policy: XmlPolicy:Default"
262 access-violation dumps in about two hours; zero after reverting the VM

Everything in this skill validates the package. None of it predicts whether the data model is safe for the running server. The kit was correct; the tier still fell over.

Two things follow:

  • Make the deploy bisectable. A large model deployed as one template gives you no way to narrow the cause. Splitting it into cascading templates so the next deploy bisects itself is the response that session chose, and it is the right shape.
  • Take an offline checkpoint and expect to use it. The revert worked and was the correct call. Budget for it rather than treating it as the unhappy path.

⚠ And weigh the blast radius before asking for a revert on a shared VM: it discards everyone's writes since the checkpoint, not just yours. Ask who else has touched the tier since.

★★ A retraction has to travel, and a check travels further than a note

Requirement 2 above was wrong, and the route it took matters more than the fact:

  • its author measured it, wrote it in a README, then retracted it in that file
  • I read the pre-retraction version, believed it, and hardened it into an enforced check in this skill
  • the check would have failed every project until the reader created four directories that do nothing

Two habits fall out, one for each end:

  • When you retract something you have already told someone, tell them. A retraction that lives only where the claim lived reaches only people who go back and re-read, and nobody re-reads a settled question.
  • Re-measure an inherited claim before enforcing it, and when the source retracts one, re-measure the retraction too rather than flipping the bit. Both reversals here were correct, and I confirmed each independently before acting.

A wrong check is worse than a wrong note. A note invites doubt. A check gets obeyed, and obeying it produces four unjustifiable directories and no failure to prompt the question. Be slower to add a check than to add a sentence.

★★ A verified result has a shelf life

Every grounding rule in this workspace is about a claim being true when made. Nothing re-checks whether it is still true when read, and a status report or a roadmap note is read hours or days later by definition.

A deploy here was verified properly, with controls, and reported as shipped. The VM was then reverted and the same verification would have returned the opposite answer within the hour. Nothing about the original verification was wrong.

Re-verify before a claim is acted on, not only before it is written. On a shared VM with checkpoints, "I verified this" carries a timestamp whether you write one or not. And when you correct such a claim, grep for every artefact carrying it: the same sentence had been fixed in a roadmap item and missed in a weekly report.

Related

tc-deployment-center (what to do with the kit once it builds), tc-vm-operations, tc-verify-and-cleanup.


Generated from skills/tc-bmide-project-validation/SKILL.md in the tc-automation-skills library, which is the canonical copy and also serves as the agent skill set for Teamcenter work.