Skip to content

fix: /PUT state not following spec with 409 - Conflict - #105

Open
chomatdam wants to merge 1 commit into
yetanalytics:masterfrom
pelotech:fix/put-state
Open

fix: /PUT state not following spec with 409 - Conflict#105
chomatdam wants to merge 1 commit into
yetanalytics:masterfrom
pelotech:fix/put-state

Conversation

@chomatdam

@chomatdam chomatdam commented Feb 10, 2026

Copy link
Copy Markdown
Contributor

Problem

State resources (/xapi/activities/state) were incorrectly subject to concurrency header requirements (If-Match / If-None-Match) when a document already existed. Per the xAPI 1.0.3 spec §3.1 and xAPI 2.0.0, state resources are explicitly exempt from concurrency header requirements:

"The State Resource will permit PUT, POST and DELETE requests without concurrency headers, since state conflicts are unlikely."

This meant that a second PUT to a state resource (overwriting an existing document) without concurrency headers would incorrectly return a 409 Conflict instead of succeeding.

Impact

(since last LRSQL release)

Articulate Storyline/Rise courses using scormdriver.js for xAPI communication do not send If-Match or If-None-Match headers when updating state documents. This caused state PUT requests to fail with 409 Conflict when a state document already existed, breaking Articulate content playback and progress tracking.

Changes

src/main/com/yetanalytics/lrs/pedestal/routes/documents.cljc

  • Added state resource exemption: when params-type is :xapi.activities.state.PUT.request/params, PUTs without concurrency headers are allowed regardless of whether a document already exists

src/test/com/yetanalytics/lrs_test.clj

Added document-concurrency-test that validates version-aware concurrency behavior:

Resource Version No existing doc Existing doc (no headers)
State 1.0.3 204 ✅ 204 ✅
State 2.0.0 204 ✅ 204 ✅

@chomatdam

Copy link
Copy Markdown
Contributor Author

I opened an issue regarding 2.0.0 conformance tests not matching the spec:
adlnet/lrs-conformance-test-suite#282

@milt
milt self-requested a review August 10, 2026 19:17
@milt

milt commented Aug 10, 2026

Copy link
Copy Markdown
Member

Thanks again @chomatdam and apologies for not getting to this sooner. I agree completely with your analysis here, it does seem to be optional for state and that is a defect. The fact that it is encoded in the conformance tests is a real problem for us too, we are currently involved in efforts to get those tests supported and hosted again as part of the I2IDL project but that will take some time. In the meantime I'm considering a runtime flag that will correct the behavior so that scormdriver.js stuff works, stay tuned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants