Community Spring Cleaning week is here! Join your fellow Maveryx in digging through your old posts and marking comments on them as solved. Learn more here!

Dev Space

Customize and extend the power of Alteryx with SDKs, APIs, custom tools, and more.
SOLVED

Invalid package file when posting workflow to Gallery

tlarsen7572
11 - Bolide
11 - Bolide

I have run into another issue posting a workflow to my gallery.  I am able to push yxzp files, but I want to try pushing yxmd or yxwz files as well.  From what I can tell, yxzp files are simple zip files with all of the workflows/macros/assets bundled together.  However, when I create a zip file containing my yxmd and send it to the server, I keep getting response 400, "Invalid package file".  The stack trace from the gallery log looks like this:

 

2019-05-22 18:40:52.544007,ERROR,156,ErrorHandler,HandleError,,,,,,,,,,Exception caught by ErrorHandler and marshalled to client,"Alteryx.Cloud.Common.Exceptions.BadRequestException: Invalid package file.->   at Alteryx.Cloud.Engine.AppEngine.LoadWorkflowDocument(String documentXml)->   at Alteryx.Cloud.Engine.AppEngine.GetWorkflowsFromPackage(String packageFile)->   at Alteryx.Cloud.Models.Presenters.AdminApiPresenter.PublishApp(AppFileInfo fileInfo, ExecutionModeType runMode, Int32 validationPriority, String requestId)->   at Alteryx.Cloud.Models.Presenters.AdminApiPresenter.<PublishAppAsync>d__24.MoveNext()->--- End of stack trace from previous location where exception was thrown ---->   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()->   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)->   at Alteryx.Cloud.Server.Services.Api.AdminApiServiceV1.<PublishYxzp>d__10.MoveNext()->--- End of stack trace from previous location where exception was thrown ---->   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()->   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)->   at System.ServiceModel.Dispatcher.TaskMethodInvoker.<InvokeAsync>d__16.MoveNext()->--- End of stack trace from previous location where exception was thrown ---->   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()->   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)->   at System.ServiceModel.Dispatcher.TaskMethodInvoker.InvokeEnd(Object instance, Object[]& outputs, IAsyncResult result)->   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeEnd(MessageRpc& rpc)->   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage7(MessageRpc& rpc)->   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)"

 

 

The body of my request, containing the bytes of my generated zip file, looks like this:

 

b'--0e5d695af01618a37eea7a73d8103b0a\r\nContent-Disposition: form-data; name="file"; filename="TestNoMacro.yxmd"\r\n\r\nPK\x03\x04\x14\x00\x00\x00\x08\x00\xa0z\xb6N\xc8SK\x14\x80\x02\x00\x00\x91\x05\x00\x00\x10\x00\x00\x00testnomacro.yxmduT\xdb\x8e\xda0\x10\xfd\x15+\x1f@\xd8\xb6\x0f}\x08Y\xb1\x1bv\x8b\x04\x0b\x82h+\xf5\xa5\xf2&C\xb0\xeax"_X\xd2\xaf\xef8!\x04\x08}\xf2x\xce\\\xcf\x8c\x1d=\x1eK\xc9\x0e\xa0\x8d@5\t\x1eF\xe3\xe01\x8e\xa6\xd2\x82\xae\x8f\tf\xae\x04eY},\xf3w\xd0\x93\xe0\xcb\xf8\xe1\xfb\xe8[\x10Go\x98\x83i\x0f\x96"\xcay2\t\xbe\x92\xfe\xd5\x89-X+Ta\xd8Z\xbaBP\xd0S\xb4\'n\xa0U\x19\xb2\x1a\xa5p\xb4sU9\xdbK\xe4\xbfF#,\x95\xc2\x8eT\xcc\xf8K\xc0\xea\xf6\x0c\xe3(\xbc\x88M\x86\x1a+\xd0V\xf8*\x9eQ\xedD\xe14\xf7\x9eT\x94+7\xf8i\xd8\x81K\x07\xe4\xee\x9d_\x04\xc8\xdc\x9cN\xa6xI@#7h\xd8\xc1\t\xb7<\x8et\x1ce\xf14\n3BH\x0e[mx\x93f\xaa\x14\xdaFf\x890\x95\xe4\xf5\x92\xd8\x98\x04cO\x0f%\xa0\xb8\t\xec\xb8\x93\xb6\xb7\xf4\xad\x92~\x01;\xdb\x95\xf7\xc2\xa5\x81\xa6\x88\xde\x8c.\x97\xfd\xcd\x14\x91\x06g^\xdbk"\xe5=j[p\x94K\x19\xf4\x863eu\xbdF\xa1\xec\xd9\xa5\'\xdd\xa7\xf6s<\x1d-\x9f\n2_\x88\t\xaf\x99^B\x89\xbafy\xdb\xd7$H\xb5kj\x7f\x95\xf8\xc1\xe5\x062\xd4\xf9B\x94\xe2\xdc\xdd\xd8\xa3)\x94\xd5\x8b\x90`\x86\x8e\x17$\xfa\xfdk\xd4L\xa8L\xba\x1c\xfc^\xbd\xb5\x93\xea8\xa2\xca\x0e3\xadQ_%y\x18\x0f\xb1\xdf[\x8b\xd5\x80\xe3g\xae2\x90+\xd5\xd8\rP\x1a#\xff\x90\xf0\xa4i{`\x80\xce\x94\x07\xd7\xa0w\xa8K\x1f\x87\x88\xd9\tI#\xf9_\xa0\xa9\x94+g\x89\xe3\x81\xc1v\x8f\x9f\x84.y\xa6q\t\xc6\xf0\x02\xcc]\xa3~\x14[\xa2\xc9\x99\xb9Y\xa9\xce\xb0\xe3\xf0\x9e\xddJ\xc9\xfa\xe7\x1e\xd4\xc6)uQa\xe7\xf2\x0b\xb1\\\xc0\x01\xe4\xd5\x9c\x16\xbcFg\xd3\xba\x82\xf8\x07j\xf1\x17\x95\xe52\n/\xd4\xb4\x00\x96\xcf\xd5\x0e\xdb\x15\x9f\x1b?V/\xdd&\xf0\xba8\x05c\xdf\xb0i\x92v\xcbk\xe8E\x98L\x8b\xca\x17JV\x1bD\xdbM\xd9\xef\t\x89\xef\xedWt\xba\xcdU\xf2qg\x88\x16\nZ\xc3\x93\xd7\x16\xb8\xce\xf6)/\xfc\xb2N\x9d\xdd\xa3n\xb6\xa1\xac\xb8\xaa\x1b\xa9\xaa\xb5(\xf66\xbcJ\xbf\x10\xea\x0f\xe3\x99u\x9c\xdeQ\xc0\xf2\xf6\tCN\x17?\xec#/+9(\xd8\xb7\xeb\xdf\xcb\x19\x0e{Bf\x07\xfa*M\xb7\'\xf9-#a\x87_=\xed\xf0\xe6\xab\x8d\xff\x01PK\x01\x02\x14\x00\x14\x00\x00\x00\x08\x00\xa0z\xb6N\xc8SK\x14\x80\x02\x00\x00\x91\x05\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x01\x00\x00\x00\x00testnomacro.yxmdPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00>\x00\x00\x00\xae\x02\x00\x00\x00\x00\r\n--0e5d695af01618a37eea7a73d8103b0a\r\nContent-Disposition: form-data; name="name"\r\n\r\nTest\r\n--0e5d695af01618a37eea7a73d8103b0a\r\nContent-Disposition: form-data; name="owner"\r\n\r\nusthlar@us.abb.com\r\n--0e5d695af01618a37eea7a73d8103b0a\r\nContent-Disposition: form-data; name="validate"\r\n\r\nfalse\r\n--0e5d695af01618a37eea7a73d8103b0a\r\nContent-Disposition: form-data; name="isPublic"\r\n\r\ntrue\r\n--0e5d695af01618a37eea7a73d8103b0a\r\nContent-Disposition: form-data; name="sourceId"\r\n\r\n\r\n--0e5d695af01618a37eea7a73d8103b0a\r\nContent-Disposition: form-data; name="workerTag"\r\n\r\n\r\n--0e5d695af01618a37eea7a73d8103b0a\r\nContent-Disposition: form-data; name="canDownload"\r\n\r\ntrue\r\n--0e5d695af01618a37eea7a73d8103b0a--\r\n'

 

 

I am generating the zip file using this Python code:

 

def zip_package(package: Dict[str, PackageFile]) -> bytes:
    zip_bytes = BytesIO()
    zip_file = zipfile.ZipFile(zip_bytes, mode="w", compression=zipfile.ZIP_DEFLATED, allowZip64=True)
    for key in package.keys():
        package_file = package[key]
        package_file_str = b"<?xml version=\"1.0\"?>" + ET.tostring(package_file.Xml, encoding="utf-8", method="xml")
        zip_file.writestr(package[key].Filename, package_file_str)
    zip_file.close()
    zip_bytes.seek(0)
    return zip_bytes.read()

 

 

Is my assumption that yxzp files are simple zip files accurate?  Or is there more to it?  Is there a particular zip algorithm I should be using?  The zip file my code generates can be opened in File Explorer and contains workflows which I am able to open in Designer, so I don't think it's a matter of my code creating a malformed workflow.

5 REPLIES 5
patrick_digan
17 - Castor
17 - Castor

@tlarsen7572 For what it's worth, when I open a yxzp using 7-zip and then go to file >>> properties, there is a comment field that contains the exact name of the worflow inside the yxzp:

Capture.PNG

It seems like a stretch, but that would be one difference between your yxzp and a standard yxzp.

tlarsen7572
11 - Bolide
11 - Bolide

@patrick_digan, you sir, are awesome!  That is exactly what the problem was.

saschamertens
5 - Atom

Hi @tlarsen7572 & @patrick_digan,

 

we just ran into the same issue and got a 400 error response from POSTing a zipped yxmd into a yxzp.

The package was zipped by 7zip command line using zip deflate method.

 

Opening the package in Designer works fine but Server denies to accept the upload.

Adding the comment manually via 7zip interface doesn't work either 😞

What still looks different after commenting in comparison to the original yxzp is that the comment seems to sit on the yxmd file in the package and not the package file itself.  

 

Do you have any ideas what that could be?

 

Kind regards,

Sascha

ananthtony
6 - Meteoroid

Hope this is resolved for you. But here is what we did to successfully migrate it. Below is the code 

 

with ZipFile(destname, 'a') as testzip:
testzip.comment = b'workflow.yxmd'

ananthtony
6 - Meteoroid

@patrick_digan Followed the instruction and I am was able to successfully update the YXZP and was able to migrate to another server. We have a server data connection with the same name created in both the source and target server.

  • Created a basic workflow to read the data from a table using the data connection in designer and saved it to source alteryx server. 
  • Packaged the workflow using the server API.
  • Updated the connection ID to target ID in the YXMD file and re-packaged it.
  • Migrated to Target server successfully using the API.
  • When we run the workflow on the server we got the error "Unable to translate the Alias <connection name>". 
  • We tried to pull the workflow from Target server on to Designer and when we check the dependencies we are seeing the error "Format of the initialization string does not conform to specification starting"
  • If we update the workflow and manually provide the target connection and then save to gallery then the workflow is running fine.

Could you please let me know if you have any solution for this?

Appreciate your help.