{"record":{"id":"30e4758f5bfd2cee","repo":"anomalyco/sst","slug":"failed-to-create-form-part-s-w","errorCode":null,"errorMessage":"failed to create form part %s: %w","messagePattern":"failed to create form part (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/server/resource/cloudflare-worker-assets.go","lineNumber":249,"sourceCode":"\t\t}\n\t\t\n\t\t// Read file content\n\t\tabsFilePath := filepath.Join(directory, fileKey)\n\t\tfileContent, err := os.ReadFile(absFilePath)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to read file %s: %w\", absFilePath, err)\n\t\t}\n\t\t\n\t\t// Base64 encode the file content\n\t\tencodedContent := base64.StdEncoding.EncodeToString(fileContent)\n\t\t\n\t\t// Create form field with content type header\n\t\tpart, err := writer.CreatePart(map[string][]string{\n\t\t\t\"Content-Disposition\": []string{fmt.Sprintf(`form-data; name=\"%s\"; filename=\"%s\"`, hash, hash)},\n\t\t\t\"Content-Type\":        []string{contentType},\n\t\t})\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to create form part %s: %w\", hash, err)\n\t\t}\n\n\t\t_, err = part.Write([]byte(encodedContent))\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"failed to write encoded content for %s: %w\", hash, err)\n\t\t}\n\t}\n\terr := writer.Close()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to close writer: %w\", err)\n\t}\n\n\turl := fmt.Sprintf(\"https://api.cloudflare.com/client/v4/accounts/%s/workers/assets/upload?base64=true\", accountId)\n\n\treq, err := http.NewRequest(\"POST\", url, &body)\n\tif err != nil {\n\t\treturn \"\", err\n\t}","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/anomalyco/sst/blob/a0bd20f762883e72a35caccb4896c42ce5b3f707/pkg/server/resource/cloudflare-worker-assets.go#L231-L267","documentation":"uploadAssets builds a multipart/form-data body for Cloudflare's Workers Assets upload API. This error wraps a failure from mime/multipart Writer.CreatePart, which fails only if the multipart writer's boundary could not be generated or the header map is malformed (e.g. nil/empty header values). It is nearly always a symptom of the internal writer being in a bad state rather than user input.","triggerScenarios":"Writer.CreatePart returns non-nil err while iterating asset hashes in uploadAssets (pkg/server/resource/cloudflare-worker-assets.go:249); in practice this happens only when the multipart.Writer is corrupted or the Content-Disposition/Content-Type header map yields invalid MIME headers (e.g. empty hash or contentType producing a malformed header value).","commonSituations":"An asset with an empty hash or empty contentType string reaching the loop; programmatic misuse after the writer was already closed; extremely rare mime/multipart edge cases with non-ASCII header values.","solutions":["Verify every asset has a non-empty hash and contentType before calling uploadAssets","Recreate the multipart.Writer if it was previously closed or reused","Check the wrapped cause (%w) with errors.Unwrap to see the underlying mime error","Upgrade/patch the code to skip assets with empty hash/contentType instead of building a part"],"exampleFix":"// before\npart, err := writer.CreatePart(map[string][]string{\n\t\"Content-Disposition\": []string{fmt.Sprintf(`form-data; name=\"%s\"; filename=\"%s\"`, hash, hash)},\n\t\"Content-Type\":        []string{contentType},\n})\n// after\nif hash == \"\" || contentType == \"\" {\n\treturn \"\", fmt.Errorf(\"invalid asset: hash=%q contentType=%q\", hash, contentType)\n}\npart, err := writer.CreatePart(map[string][]string{\n\t\"Content-Disposition\": []string{fmt.Sprintf(`form-data; name=%q; filename=%q`, hash, hash)},\n\t\"Content-Type\":        []string{contentType},\n})","handlingStrategy":"validation","validationCode":"for hash, contentType := range assets {\n\tif hash == \"\" || contentType == \"\" {\n\t\treturn fmt.Errorf(\"invalid asset entry: hash=%q contentType=%q\", hash, contentType)\n\t}\n}","typeGuard":"func validAsset(hash, contentType string) bool {\n\treturn hash != \"\" && contentType != \"\"\n}","tryCatchPattern":"part, err := writer.CreatePart(headers)\nif err != nil {\n\treturn \"\", fmt.Errorf(\"failed to create form part %s: %w\", hash, err)\n}","preventionTips":["Validate hash and contentType are non-empty before building parts","Never reuse a multipart.Writer after Close","Unwrap and log the underlying mime error for diagnosis"],"tags":["cloudflare","multipart","workers-assets","upload"],"backgroundTag":"multipart-form-creation-failed","analyzedSha":"a0bd20f762883e72a35caccb4896c42ce5b3f707","analyzedAt":"2026-08-30T11:26:00.383Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}