anomalyco/sst · error

failed to marshal metadata: %w

Error message

failed to marshal metadata: %w

What it means

Returned when json.Marshal fails to serialize the metadata map produced by buildMetadata(input) for the Worker script upload. In practice map[string]interface{} with the current builder values (strings, bools, nested maps) always marshals, so this is a defensive guard that would only fire if unsupported types (channels, funcs, NaN-like values) were ever added to the metadata. Raised in handleUpdate during Create/Update.

Source

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

	}

	_, 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 {
		return fmt.Errorf("failed to marshal metadata: %w", err)
	}

	_, err = metadataPart.Write(metadata)
	if err != nil {
		return fmt.Errorf("failed to write file content for metadata: %w", err)
	}

	// Close writer
	err = writer.Close()
	if err != nil {
		return fmt.Errorf("failed to close writer: %w", err)
	}

	url := fmt.Sprintf("https://api.cloudflare.com/client/v4/accounts/%s/workers/scripts/%s", input.AccountId, input.ScriptName)

	req, err := http.NewRequest("PUT", url, &body)
	if err != nil {
		return err

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Inspect any local changes to buildMetadata for non-JSON-serializable values
  2. Convert custom fields to JSON-safe types (string, bool, number, slice, map)
  3. Check the wrapped error message for the unsupported Go type name

Example fix

// before
metadata["custom"] = someChannel
// after
metadata["custom"] = fmt.Sprintf("%v", someChannel)
Defensive patterns

Strategy: validation

Validate before calling

func validateMetadata(m map[string]interface{}) error {
    _, err := json.Marshal(m)
    return err
}

Type guard

func jsonSafe(v interface{}) bool {
    switch v.(type) {
    case chan interface{}, func(), complex128, complex64:
        return false
    }
    return true
}

Try / catch

null

Prevention

When it happens

Trigger: json.Marshal(buildMetadata(input)) returns an error, i.e. the metadata map contains a value json cannot encode (unsupported type, cyclic reference).

Common situations: Modifying buildMetadata to include unsupported Go values (channels, functions, complex numbers); otherwise essentially unreachable in current code.

Related errors


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