How can I replace documents using the new UI Designer ?


Hi everybody,

After burning my brains out over this new UI Designer + Contrac t interface, I decided to cry for the help of my community fellows. I need to have the same options offered in Bonita 6.x forms for a document, but now on a Bonita 7 (AngularJS/Bootstrap): KEEP, REMOVE, MODIFY. I show a document in a form, using the HTTP widget. I also place an Upload widget on the form, so the user may replace the original file. So far so good, but the possibility of changing the file demands that I use a CONTRACT and because of that I must offer some JSON to it when the form is submitted. The problem is that the CONTRACT does not accept the context.document_ref as the old file JSON. When I try it, the following error occurs:

"exception":"class org.bonitasoft.engine.bpm.contract.ContractViolationException","message":"Error while validating expected inputs","explanations":["{id=8, processInstanceId=9, name=docsAnexados, author=3, creationDate=1438739037778, fileName=camiseta.JPG, contentMimeType=image/jpeg, contentStorageId=8, url=documentDownload?fileName=camiseta.JPG&contentStorageId=8, description=, version=1, index=-1, contentFileName=camiseta.JPG} cannot be assigned to FILE"]

The question is: how can I submit a valid JSON about the old file to the CONTRACT, since all I have is the context.document_ref one. The logic itself is ok because when I submit the JSON of the new file (obtained from the Upload widget) everything goes smoothy.



2 answers



Using Bonita BPM 7.0 you should be able to achieve your use case. The short answer is, you should take care of this, in the process, not in the form.

Detailed answer is:

From the form point of view (keep doing what you are doing)
* display the document

  • provide a file upload in case of new version of the document

  • if the user provide a file, send it as part of the JSON, if not, keep the file value to null

From the process point of view:

  • declare your human task to take a file as an input. By default an input accepts to receive a null value, which is what you want in case of your user does not provide a new file.

  • in the operation where you handle your document as right hand side operand, do not use the input directly but a Groovy expression. If the input is NOT null, then use it, else, get the current value of the document from the API and re-use it.

Hope this answer the question,
Captain Bonita


Submitted by truc.nguyen on Thu, 08/13/2015 - 15:39


I successfully tested Captain Bonita's solution. \o/

So the trick was to send something like:

  • in case of file upload (replacing current document):
"my_file": {
    "tempPath": "tmp_2185924842868621981.pdf",
    "filename": "the_document.pdf"
  • in case of keeping current document:
"my_file": null

Then in your process the Groovy script used in the operation setting the document would look like:

import org.bonitasoft.engine.bpm.document.DocumentValue;

DocumentValue dv;

if (my_file == null) {
    byte[] content = apiAccessor.getProcessAPI().getDocumentContent(document.getContentStorageId());
    dv = new DocumentValue(content, document.getContentMimeType(), document.getContentFileName());
else {
    dv = new DocumentValue(my_file.getContent(), null, document.getFileName());

return dv;


Submitted by logicallimit on Sun, 02/21/2016 - 11:34

Hi, Can you please tell me what exactly you wrote in the code on form to get following:

"tempPath": "tmp_2185924842868621981.pdf",
"filename": "the_document.pdf"

How did you get these two file names.

Moreover, will this code change show result on a process already started. There are three file upload widget on my approver screen for which files were already uploaded by data entry operator. When I submit without selecting a file in file upload widgets, i get following error: ["{} cannot be assigned to FILE","{} cannot be assigned to FILE","{} cannot be assigned to FILE","{outletAddressUrban=null, outletLocationType=null, outletLevelGPDetail=null, outletNameEng=null, applicationNo=null, outletAddressRuralGP=null, processingFeeAmt=null, outletOwnerEmail=null, enclIsBACDUploaded=null, isOutletLevelTehsil=null, formFilledBy=null, outletContactPersonName=null, outletEmail=null, outletPoliceStation=null, isOutletLevelDistrict=null, outletLevelDistrictDetail=null, processingFeeRefNo=null, outletLevelTehsilType=null, voterId=null, enclIsPVRUploaded=null, jobFeeRefNo=null, pan=null, outletOwnerName=null, outletBankName=null, longitude=null, outletOwnerPermanentAddress=null, currentApplicationStatus=null, formFilledAt=null, enclIsECUploaded=null, jobFeeAmt=null, enclIsJobFeeDetailUploaded=null, outletBankAccNo=null, district=null, outletLevelPSBType=null, outletAddressUrbanMT=null, outletNameHnd=null, latitude=null, lsp=null, outletBankAccIFSCCode=null, outletBankAccHolderName=null, outletLevelPSBDetail=null, enclIsIdProofUploaded=null, isOutletLevelGP=null, outletOwnerType=null, outletAddressRural=null, iConfirm=null, outletOwnerMobileNo=null, outletOwnerPhoneNo=null, outletAddressRuralV=null, aadhaar=null, outletPhoneNo=null, outletLevelVillageDetail=null, outletLevelGPType=null, oldOutletId=null, outletLevelDistrictType=null, isOutletLevelPSB=null, outletLevelVillageType=null, outletBankBranchName=null, isOutletLevelVillage=null, outletAddressRuralPS=null, outletAddressUrbanWN=null, outletAddressUrbanPC=null, applicationSubmissionDate=null, outletMobileNo=null, outletLevelTehsilDetail=null, oldLSPName=null, enclIsProcessingFeeDetailUploaded=null, outletAddressRuralPC=null, remarks=null} cannot be assigned to COMPLEX type"]

Following is my script code for first upload widget at process level:

import org.bonitasoft.engine.bpm.document.DocumentValue
DocumentValue enclBACDFileDocumentValue = null
if(enclBACDFileDocumentInput == null){
byte[] content = apiAccessor.getProcessAPI().getDocumentContent(enclBACDFile.getContentStorageId());
enclBACDFileDocumentValue = new DocumentValue(enclBACDFileDocumentInput.getContent(), null, enclBACDFile.getFileName());

return enclBACDFileDocumentValue

enclBACDFileDocumentInput is a variable shown in the dropdown of edit expression screen below the name of expression. The variable type is : org.bonitasoft.engine.bpm.contract.FileInputValue

Pls help.


Hi Ricardo,

Thanks for using Bonita BPM 7 and its new concepts.

Currently a contract input of type FILE always expects a file to be uploaded. Therefore re-using an existing document to validate the contract is not supported yet. This fact will be reported in our internal issue tracking system shortly.


Besides in order to get the expected JSON values to send one can use the contract REST API resource as follows: - GET | /API/bpm/process/8902137890939378455/contract Documentation: - GET | /API/bpm/userTask/20004/contract Documentation:

Using the contract REST API then helps to determine that a FILE contract input expects a JSON payload as follows:

"my_file": {
    "tempPath": "tmp_2185924842868621981.pdf",
    "filename": "the_document.pdf"

Others may have other ideas to work around this limitation in the meantime. Kind regards.


Submitted by Sean McP on Wed, 08/05/2015 - 18:50


I hope shortly in the following sentence means NOW...

This fact will be reported in our internal issue tracking system shortly.

This is vital to my processes and if not possible I simply have to STOP all work on 7 completely

Simply not acceptable to wait for this, has to be made available ASAP.

Many thanks and best regards Seán

Submitted by truc.nguyen on Thu, 08/06/2015 - 10:31

Hi Sean,

Yes, it means NOW. The issue has been reported, analyzed and targeted for early September maintenance release.

Thanks again for your understanding and your huge contribution to the community.

Best regards. Truc

Submitted by logicallimit on Sun, 02/28/2016 - 13:01


Can you please tell how will we pass the value of a text box field also along with the JSON data to backend. I have a form with 6 file upload control and multiple other text boxes and html controls. Bonitasoft by default generates a formOutput variable of type javascript expression when form is generated from contract. But in this case, it has to be a JSON. I am not sure how to send data of text boxes and other fields along with the file data (if uploaded). Can you please give some hint with code.