anomalyco/sst · error

failed to create form part %s: %w

Error message

failed to create form part %s: %w

What it means

This error wraps a failure from mime/multipart.Writer.CreatePart while building the multipart body used to PUT a Worker script to the Cloudflare API. CreatePart only fails if the multipart writer was already closed or the underlying buffer cannot accept a new part header, so it is nearly always a programming/lifecycle bug rather than a user input problem. It is returned by handleUpdate, which backs both Create and Update of the WorkerScript resource.

Source

Thrown at pkg/server/resource/cloudflare-worker-script.go:171

	// Add file content to form data
	fileContent, err := os.ReadFile(input.Content.Filename)
	if err != nil {
		return fmt.Errorf("failed to read file %s: %w", input.Content.Filename, err)
	}

	contentType := "application/javascript"
	if input.MainModule != "" {
		input.MainModule = input.Content.Hash
		contentType = "application/javascript+module"
	}

	contentPart, err := writer.CreatePart(map[string][]string{
		"Content-Disposition": []string{fmt.Sprintf(`form-data; name="%s"; filename="%s"`, input.Content.Hash, input.Content.Hash)},
		"Content-Type":        []string{contentType},
	})
	if err != nil {
		return fmt.Errorf("failed to create form part %s: %w", input.Content.Hash, err)
	}

	_, err = contentPart.Write([]byte(fileContent))
	if err != nil {
		return fmt.Errorf("failed to write file content for %s: %w", input.Content.Hash, err)
	}

	// Add metadata to form data
	metadataPart, err := writer.CreatePart(map[string][]string{
		"Content-Disposition": []string{`form-data; name="metadata"`},
		"Content-Type":        []string{"application/json"},
	})
	if err != nil {
		return fmt.Errorf("failed to create form part metadata: %w", err)
	}

	metadata, err := json.Marshal(buildMetadata(input))
	if err != nil {

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Check that no code path calls writer.Close() before this CreatePart call; all CreatePart/Write calls must precede Close
  2. Re-run the deploy — this is deterministic, so if it persists inspect custom modifications to cloudflare-worker-script.go
  3. Report upstream with the wrapped inner error (%w) if it occurs on an unmodified checkout

Example fix

// before
err = writer.Close()
contentPart, err := writer.CreatePart(headers) // fails: writer closed
// after
contentPart, err := writer.CreatePart(headers)
// ... write all parts ...
err = writer.Close()
Defensive patterns

Strategy: try-catch

Validate before calling

if input.Content.Hash == "" { return errors.New("content hash required before upload") }

Try / catch

err := r.handleUpdate(input)
if err != nil {
    var wrap *fmt.wrapError
    if errors.As(err, &wrap) { log.Printf("multipart failure: %v", wrap.Unwrap()) }
    return err
}

Prevention

When it happens

Trigger: writer.CreatePart returns an error while creating the content part for input.Content.Hash — practically only when the multipart.Writer has already been Close()d, or an I/O error occurs writing headers into the underlying bytes.Buffer.

Common situations: Reordering the handleUpdate body so writer.Close() is called before CreatePart; writing additional parts after Close; an out-of-memory or closed-buffer condition making the bytes.Buffer write fail.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/6538ec29b6ed00e6. Report an issue: GitHub.