Summary
Software entities created via POST /software are inserted as a flat SoftwareWriteModel document, not as a StoredIdentifier wrapper. Subsequent metadata updates through PUT /ark:/{NAAN}/{postfix} persist to Mongo, but the handler then validates the full returned document as StoredIdentifier and fails with HTTP 500 because required top-level shell fields are missing (dateCreated, and often publicationStatus / distribution).
This breaks any client that updates software provenance after registration (e.g. adding usedByComputation links from a computation finalize step).
Impact
PUT /ark:/… on software registered via POST /software returns 500 Internal Server Error
The metadata update is written to Mongo before the error is returned
Clients cannot distinguish success from failure without a follow-up GET
Related endpoints that validate StoredIdentifier before/after update (e.g. PUT /publish) also fail on these documents
Downstream services treating 500 as failure block workflows even when the intended mutation succeeded
Steps to reproduce
Authenticate and create a software entity:
POST /software
Content-Type: application/json
Authorization: Bearer
{
"@id": "ark:59853/",
"@type": ["prov:Entity", "https://w3id.org/EVI#Software"],
"name": "example repository",
"description": "Example software for reproduction",
"author": "user@example.org",
"version": "abc123",
"contentUrl": "http://example.com/repo.git",
"format": "git",
"codeRepository": "http://example.com/repo.git",
"branch": "main",
"commit": "abc123"
}
Inspect the Mongo document in identifierCollection. Top-level fields look like:
{
"@id": "ark:59853/",
"@type": ["prov:Entity", "https://w3id.org/EVI#Software"],
"name": "example repository",
"permissions": { "...": "..." },
"...": "other Software fields"
}
Missing compared to dataset/computation inserts:
top-level metadata subdocument (EVI payload nested under metadata)
top-level publicationStatus
top-level dateCreated
top-level dateModified
top-level distribution (optional but expected in shell)
Update the entity via the resolver:
PUT /ark:/59853/
Content-Type: application/json
Authorization: Bearer
{
"@id": "ark:59853/",
"@type": ["prov:Entity", "https://w3id.org/EVI#Software"],
"name": "example repository",
"usedByComputation": [{ "@id": "ark:59853/" }]
}
Observe:
HTTP 500 Internal Server Error
Server log: ValidationError on StoredIdentifier — missing dateCreated (and related shell fields)
Mongo was updated: metadata.usedByComputation contains the new link
Expected behavior
POST /software should insert documents in the same StoredIdentifier shape used by createComputation / dataset registration
PUT /ark:/… should return 200 with the updated identifier when the metadata write succeeds
If validation fails, the update should be rolled back (or validation should happen before the write)
Actual behavior
POST /software inserts a flat document via SoftwareWriteModel
PUT /ark:/… performs $set: { metadata: … }, then validates the post-update document as StoredIdentifier
Validation fails on missing top-level shell fields → 500, even though Mongo already contains the new metadata
Summary
Software entities created via POST /software are inserted as a flat SoftwareWriteModel document, not as a StoredIdentifier wrapper. Subsequent metadata updates through PUT /ark:/{NAAN}/{postfix} persist to Mongo, but the handler then validates the full returned document as StoredIdentifier and fails with HTTP 500 because required top-level shell fields are missing (dateCreated, and often publicationStatus / distribution).
This breaks any client that updates software provenance after registration (e.g. adding usedByComputation links from a computation finalize step).
Impact
PUT /ark:/… on software registered via POST /software returns 500 Internal Server Error
The metadata update is written to Mongo before the error is returned
Clients cannot distinguish success from failure without a follow-up GET
Related endpoints that validate StoredIdentifier before/after update (e.g. PUT /publish) also fail on these documents
Downstream services treating 500 as failure block workflows even when the intended mutation succeeded
Steps to reproduce
Authenticate and create a software entity:
POST /software
Content-Type: application/json
Authorization: Bearer
{
"@id": "ark:59853/",
"@type": ["prov:Entity", "https://w3id.org/EVI#Software"],
"name": "example repository",
"description": "Example software for reproduction",
"author": "user@example.org",
"version": "abc123",
"contentUrl": "http://example.com/repo.git",
"format": "git",
"codeRepository": "http://example.com/repo.git",
"branch": "main",
"commit": "abc123"
}
Inspect the Mongo document in identifierCollection. Top-level fields look like:
{
"@id": "ark:59853/",
"@type": ["prov:Entity", "https://w3id.org/EVI#Software"],
"name": "example repository",
"permissions": { "...": "..." },
"...": "other Software fields"
}
Missing compared to dataset/computation inserts:
top-level metadata subdocument (EVI payload nested under metadata)
top-level publicationStatus
top-level dateCreated
top-level dateModified
top-level distribution (optional but expected in shell)
Update the entity via the resolver:
PUT /ark:/59853/
Content-Type: application/json
Authorization: Bearer
{
"@id": "ark:59853/",
"@type": ["prov:Entity", "https://w3id.org/EVI#Software"],
"name": "example repository",
"usedByComputation": [{ "@id": "ark:59853/" }]
}
Observe:
HTTP 500 Internal Server Error
Server log: ValidationError on StoredIdentifier — missing dateCreated (and related shell fields)
Mongo was updated: metadata.usedByComputation contains the new link
Expected behavior
POST /software should insert documents in the same StoredIdentifier shape used by createComputation / dataset registration
PUT /ark:/… should return 200 with the updated identifier when the metadata write succeeds
If validation fails, the update should be rolled back (or validation should happen before the write)
Actual behavior
POST /software inserts a flat document via SoftwareWriteModel
PUT /ark:/… performs $set: { metadata: … }, then validates the post-update document as StoredIdentifier
Validation fails on missing top-level shell fields → 500, even though Mongo already contains the new metadata