REST API update to engineering change order fails with 409 Conflict error

I’m building an ECO automation workflow and consistently getting 409 Conflict errors when trying to update engineering change orders via REST API. The lifecycle state permissions seem correct - the API user can update ECOs in the UI without issues. But programmatic updates through REST fail with conflict errors.

Here’s what’s failing:

PATCH /Windchill/servlet/odata/ChangeMgmt/ChangeOrders('OR:wt.change2.WTChangeOrder2:12345')
{
  "Description": "Updated scope",
  "Priority": "High"
}

The ECO is in INWORK state, and the REST API update restrictions don’t seem to be documented clearly for 12.0. The ECO workflow configuration allows updates at this state, so I’m confused why REST behaves differently. Is there a state-specific restriction on REST updates that doesn’t apply to UI updates?

ECO workflow configuration can definitely cause 409 errors if the workflow is actively processing the object. When an ECO is at a workflow decision point or has pending assignments, Windchill locks it to prevent state inconsistency. Your API user might have permission to update the ECO, but the workflow process temporarily blocks modifications until assignments complete. Check if your ECO has active workflow tasks in Workflow Administrator. If there’s a pending assignment or the workflow is mid-transition, REST updates will fail even though UI might show the object as editable.

409 Conflict usually means concurrent modification - someone else updated the ECO between when you fetched it and when you tried to update. REST APIs use ETags for optimistic locking. You need to include the If-Match header with the current ETag value. Fetch the ECO first with GET, grab the @odata.etag value from response, then include it in your PATCH request as If-Match header.

There’s also the version issue. If you’re trying to update a specific version of the ECO and a newer version exists, you’ll get 409. Make sure your OID reference points to the latest iteration. Use the version-agnostic endpoint or explicitly fetch the latest version before updating.

Let me provide a complete solution covering all three critical areas:

1. Lifecycle State Permissions

The 409 Conflict error in your case isn’t actually about lifecycle state permissions - those would return 403 Forbidden. However, lifecycle state does interact with REST updates in important ways:

  • Verify your ECO’s lifecycle template allows modifications in INWORK state (not just view/checkout)
  • Check if lifecycle state has conditional attributes - some attributes may be read-only in certain states
  • Confirm no lifecycle validators are rejecting the update (these can manifest as 409 instead of 400)

Use this query to check current state and permissions:

SELECT statestate, checkoutInfo
FROM ChangeOrder2
WHERE ida2a2 = 12345

If checkoutInfo is not null, the ECO is checked out and REST updates will fail.

2. REST API Update Restrictions

Windchill 12.0 introduced stricter concurrency controls for change management objects. The 409 Conflict has three common causes:

A. Missing ETag (most common):

REST API requires optimistic concurrency control. You MUST include If-Match header:

GET /Windchill/servlet/odata/ChangeMgmt/ChangeOrders('OR:wt.change2.WTChangeOrder2:12345')
Response includes: "@odata.etag": "W/datetime'2025-06-08T14:15:00Z'"

PATCH /Windchill/servlet/odata/ChangeMgmt/ChangeOrders('OR:wt.change2.WTChangeOrder2:12345')
If-Match: W/"datetime'2025-06-08T14:15:00Z'"

Without If-Match, Windchill returns 409 to prevent blind overwrites.

B. Workflow Locks:

Active workflow tasks place temporary locks. Query workflow status:

// Pseudocode - Check workflow locks:
1. Get ECO object reference from OID
2. Query WfProcess for processes where primaryBusinessObject = ECO
3. Check if any process has state = ACTIVE or SUSPENDED
4. If active, wait for workflow completion or reassign/complete tasks
// See documentation: Windchill Workflow API Guide Section 6.3

C. Version Conflicts:

Ensure you’re updating the latest iteration. Use version-agnostic endpoint or verify:


GET /Windchill/servlet/odata/ChangeMgmt/ChangeOrders?$filter=Number eq 'ECO-2025-001'&$orderby=IterationIdentifier desc&$top=1

3. ECO Workflow Configuration

ECO workflow configuration has specific rules that affect REST updates:

  • Assignment-based locks: When ECO has active workflow assignments, the object is locked to assignment owners. REST updates fail with 409 until assignments complete.
  • Transition states: During workflow state transitions (e.g., from INWORK to UNDERREVIEW), there’s a brief window where the object is locked. Retry logic is essential.
  • Resulting Objects processing: If your ECO has change tasks with Resulting Objects being created/updated, those operations lock the parent ECO.

Configuration check:

Navigate to Type and Attribute Management > Change Order > Lifecycle tab. Verify:

  • INWORK state has “Allow Modify” checked
  • No workflow activities have “Lock Object” option enabled unnecessarily
  • Workflow template doesn’t have overlapping approval paths that could cause deadlocks

Complete Solution Pattern:

// Pseudocode - Robust ECO update:
1. GET ECO to retrieve current state and ETag
2. Verify lifecycle state allows modifications (not CANCELLED/CLOSED)
3. Check workflow status - if active, poll until tasks complete or timeout
4. Prepare PATCH request with If-Match header from step 1
5. Execute PATCH with retry logic (max 3 attempts, 5-second intervals)
6. On 409, re-fetch ETag and retry; on 412, refresh entire object
// See documentation: Windchill REST API Guide Section 5.2

Debugging Steps:

  1. Enable REST API debug logging: `log4j.logger.wt.rest=DEBUG
  2. Check MethodServer.log for actual conflict reason (often more detailed than API response)
  3. Verify no custom event listeners are triggering validation failures
  4. Test update on freshly created ECO without workflow to isolate workflow-related issues

Known Issue in 12.0.CPS05:

There’s a documented issue (SPR 3048291) where ECOs with more than 50 affected items return spurious 409 errors due to transaction timeout during validation. Workaround: Update ECO attributes first, then add affected items in separate API calls.

The most likely cause in your case is missing If-Match header. Implement ETag-based optimistic concurrency control and the 409 errors should resolve. If they persist after adding ETags, then investigate workflow locks and version conflicts systematically.

I checked and the ECO isn’t checked out. I’m not using ETags currently - could that really cause 409 instead of 412 Precondition Failed? The error message just says ‘Conflict’ without much detail. Let me try adding the If-Match header and see if that changes anything.