community
cancel
Showing results for 
Search instead for 
Did you mean: 

Dev Space

Customize & extend the power of Alteryx. SDKs, APIs, custom tools, and more!
Community v19.6

Looks aren't everything... But the latest Community refresh looks darn good!

Learn More
SOLVED

Invalid package file when posting workflow to Gallery

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.

Highlighted

@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.

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