API deploy returns 500 when a draft exists: PATCH /api/v2/assets/{id}/deployment/ with last deployed version_id

Hi everyone, I’m getting a 500 Internal Server Error when deploying an existing survey via the API, but only under a specific condition.

What I’m trying to do

I need to update some csv files related to a form and then re-deploy, without changing the form content itself.

To do that, I call the deployment endpoint using the survey asset id and the version_id of the last deployed version (important: the deployed one, not a draft), and set it active:

PATCH /api/v2/assets/{surveyId}/deployment/
Content-Type: application/json

{
  "version_id": "{versionId}",
  "active": true
}

What works

This API deploy call works fine as long as there is no saved draft of the form.

What fails

If I open the form in the UI, make any change, and save a draft (even if I don’t deploy it), then the exact same API call starts returning HTTP 500.

Steps to reproduce (consistent for me)

  1. Have a deployed survey (Asset A) with deployed version_id = X

  2. Call the PATCH deploy endpoint with version_id = X and active: true → :white_check_mark: works

  3. Edit the form in the UI and save a draft (creating a newer, non-deployed version)

  4. Call the same PATCH deploy endpoint again with version_id = X and active: true → :cross_mark: returns 500

Expected behavior

Either:

  • the API should redeploy the specified deployed version successfully, or

  • it should return a clear 4xx error explaining why it can’t deploy that version when a draft exists (e.g., “version is not latest”, “draft present”, etc.)

Questions

  • Is it expected that deployments via API fail with 500 when a new draft version exists?

  • Is there a recommended way to redeploy the last deployed version while keeping a draft around?

  • If this is a bug, is there a known workaround (discard draft, clone asset, etc.)?

Thanks in advance for any guidance!

Welcome to the community, @charlascuen! Did you mean you wish to redeploy your project without making any changes to the content through an API call?

Hi. Yes, I want to redeploy the last deployed version without changing the content of the survey and without deploying any drafts that could be in process. Thanks a lot for your answers

@charlascuen, if that is your requirement, then your PATCH method is correct. Your API endpoint /api/v2/assets/{surveyId}/deployment/ is also correct. You just need to use this request JSON body as shown below:

{
“active”: true
}

This should solve your issue with redeployment.

Thanks @Kal_Lam, and sorry for coming back to this. I tested it and {“active”: true}
avoids the 500, but it doesn’t solve the underlying need, so I’ve unmarked it as the
solution.

My goal is for devices to pick up updated media files (the CSVs used by
select_one_from_file), which our integration uploads daily through
/api/v2/assets/{uid}/files/. Looking at KPI, a PATCH with only “active” goes through
the branch commented “This request is only changing the active (aka archived) state”:
set_active() only updates XForm.downloadable, and the media files are only copied to
the OpenRosa manifest by sync_media_files_async() inside asset.deploy(). Since
asset.deploy() always deploys the asset’s current content, there is no way today to
push new media without also deploying a draft saved in the form builder.

Two questions:

  1. Deploying a version_id that is not the current one raises NotImplementedError in
    DeploymentSerializer._raise_unless_current_version, which surfaces as a 500. Could
    it be a 400 with that message instead? I’m happy to open a PR.
  2. Would you consider a supported way to sync form media to the deployment without
    redeploying the content (for example, an endpoint that triggers the media sync)?
    It’s what any project whose choice lists come from an external system needs.

Is there a recommended approach in the meantime?