diff --git a/api/v1/api_uploads.go b/api/v1/api_uploads.go
index 56572570a97ddf82cbe1297bc1e9a4c14b25abe7..88f8c09f2b0d1b168e87ae582830f921d3c3db5d 100644
--- a/api/v1/api_uploads.go
+++ b/api/v1/api_uploads.go
@@ -130,6 +130,8 @@ func (ch *FlowJSFileChunk) Cleanup() (err error) {
 	return os.Remove(filename)
 }
 
+//***
+
 type FlowJSFile struct {
 	id         string
 	size       uint64
@@ -192,6 +194,45 @@ func (f *FlowJSFile) Read(p []byte) (n int, err error) {
 	}
 }
 
+//***
+
+func getOrNewFlowJSFile(job *importer.Job, flowId string, chunk, totalChunks, totalSize uint64) (file *FlowJSFile, err error) {
+	var src io.Reader
+	if src, err = job.GetAttachedUploader(); err != nil && err != importer.ErrSourceNotYetAttached {
+		return
+	}
+
+	if err == importer.ErrSourceNotYetAttached {
+		if file, err = newFlowJSFile(flowId, totalChunks, totalSize, job); err != nil {
+			return
+		}
+
+		_, err = job.AttachUploader(file.size, file)
+		switch err {
+		case nil:
+		case importer.ErrSourceAlreadyAttached:
+			// there has been a race and the other thread won!
+			file = nil
+			if src, err = job.GetAttachedUploader(); err != nil {
+				return
+			}
+		default:
+			return
+		}
+	}
+
+	if file == nil {
+		var ok bool
+		if file, ok = src.(*FlowJSFile); !ok {
+			err = ErrNotFlowJSUpload
+			return
+		}
+	}
+	return
+}
+
+//***
+
 func (api *API) UploadFileFlowJS() http.Handler {
 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		// TODO: implement this
@@ -240,40 +281,10 @@ func (api *API) TestFileFlowJS() http.Handler {
 			sendError(w, err)
 			return
 		}
-		src, err := job.GetAttachedUploader()
-		if err != nil && err != importer.ErrSourceNotYetAttached {
-			sendError(w, err)
-			return
-		}
-
-		var file *FlowJSFile
-		if err == importer.ErrSourceNotYetAttached {
-			if file, err = newFlowJSFile(flowId, totalChunks, totalSize, job); err != nil {
-				sendError(w, err)
-				return
-			}
 
-			_, err = job.AttachUploader(file.size, file)
-			switch err {
-			case nil:
-			case importer.ErrSourceAlreadyAttached:
-				// there has been a race and the other thread won!
-				file = nil
-				if src, err = job.GetAttachedUploader(); err != nil {
-					sendError(w, err)
-					return
-				}
-			default:
-				sendError(w, err)
-				return
-			}
-		}
+		file, err := getOrNewFlowJSFile(job, flowId, chunk, totalChunks, totalSize)
 		if file == nil {
-			var ok bool
-			if file, ok = src.(*FlowJSFile); !ok {
-				sendWebResponse(w, http.StatusConflict, ErrorResponse{Error: "this is not a flow.js upload"})
-				return
-			}
+			sendError(w, err)
 		}
 
 		if chunk > uint64(len(file.chunks)) {
diff --git a/api/v1/utils.go b/api/v1/utils.go
index 367067b7c248eeb37c00a9fd8d26ec2448fd4507..f002536eecb453520975da17b302550ea36c260d 100644
--- a/api/v1/utils.go
+++ b/api/v1/utils.go
@@ -26,6 +26,7 @@ package v1
 
 import (
 	"encoding/json"
+	"errors"
 	"net/http"
 	"strconv"
 
@@ -33,6 +34,10 @@ import (
 	"gitlab.servus.at/autoradio/tank/store"
 )
 
+var (
+	ErrNotFlowJSUpload = errors.New("this is not a flow.js upload")
+)
+
 func idFromString(s string) (uint64, error) {
 	return strconv.ParseUint(s, 10, 64)
 }
@@ -48,6 +53,9 @@ func sendError(w http.ResponseWriter, err error) {
 		response.Details = err.(*importer.JobSourceResult).Log
 	default:
 		switch err {
+		case ErrNotFlowJSUpload:
+			code = http.StatusConflict
+
 		case store.ErrNotImplemented:
 			code = http.StatusNotImplemented
 		case store.ErrNotFound: