Skip to content
Effect 4.0 is here. One ecosystem. Zero dependencies.

Multipart unstable

Parses and persists HTTP multipart/form-data request bodies.

Multipart turns incoming byte streams into typed form parts. Text parts become decoded fields, while upload parts stay as streamed files until they are collected or written to scoped temporary files. The persisted representation can then be decoded with schemas for handlers that receive fields and uploaded files together. This module also includes multipart error types, schema helpers for persisted files, and parser limit settings.

31 exports Since v4.0.0 Source

Configuration

makeConfig

unstable
Since v4.0.0

Builds the low-level multipart parser configuration from request headers and the current fiber context.

Details

Parser limits are read from the multipart references, including maximum parts, field size, file size, total body size, and field MIME type overrides.

Signature

declare function makeConfig(headers: Record<string, string>): Effect<BaseConfig>

Converting

Since v4.0.0

Runs a channel of byte chunks and collects all output into a single Uint8Array.

Gotchas

This materializes the full content in memory. The source channel must not reuse or mutate emitted buffers, which are retained until collection completes.

Signature

declare function collectUint8Array<OE, OD, R>(self: Channel<readonly [Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>], OE, OD, unknown, unknown, unknown, R>): Effect<Uint8Array<ArrayBuffer>, OE, R>

toPersisted

unstable
Since v4.0.0

Persists a stream of multipart parts into a record.

Details

Text fields are collected as strings, and file parts are written to files in a scoped temporary directory.

Gotchas

Persisted file paths remain valid for the lifetime of the scope.

Signature

declare function toPersisted(stream: Stream<Part, MultipartError>, writeFile: (path: string, file: File) => Effect<void, MultipartError, FileSystem>): Effect<Persisted, MultipartError, Scope | FileSystem | Path>

Errors

Since v4.0.0

Error raised while parsing, streaming, or persisting multipart form data.

Details

The reason field contains the concrete MultipartErrorReason. When used as a server response, parse errors render as 400, limit errors as 413, and internal errors as 500. Multipart errors are ignored by the error reporter.

Signature

declare class MultipartError extends YieldableError<this> & {
readonly _tag: "MultipartError";
} & Readonly<{
readonly reason: MultipartErrorReason;
}> implements Respondable {
constructor(args: {
readonly reason: MultipartErrorReason;
});
readonly "~effect/ErrorReporter/ignore": true;
readonly "~effect/http/Multipart/MultipartError": "~effect/http/Multipart/MultipartError";
message: string;
"~effect/http/HttpServerRespondable"(): Effect<HttpServerResponse, never, never>;
static fromReason(reason: "InternalError" | "FileTooLarge" | "FieldTooLarge" | "BodyTooLarge" | "TooManyParts" | "Parse", cause?: unknown): MultipartError;
}
Since v4.0.0

Error reason carried by a MultipartError.

Details

It identifies parser and limit failures such as oversized files or fields, too many parts, total body size limits, parse errors, and internal errors.

Signature

declare class MultipartErrorReason extends Error<{
readonly _tag: "FileTooLarge" | "FieldTooLarge" | "BodyTooLarge" | "TooManyParts" | "InternalError" | "Parse";
readonly cause?: unknown;
}> {
constructor(args: {
readonly _tag: "InternalError" | "FileTooLarge" | "FieldTooLarge" | "BodyTooLarge" | "TooManyParts" | "Parse";
readonly cause?: unknown;
});
}

Guards

isField

unstable
Since v4.0.0

Returns true when a value is a multipart text Field.

Signature

declare function isField(u: unknown): u is Field

isFile

unstable
Since v4.0.0

Returns true when a value is a multipart File.

Signature

declare function isFile(u: unknown): u is File
Since v4.0.0

Checks whether a value is a MultipartError.

Signature

declare function isMultipartError(u: unknown): u is MultipartError

isPart

unstable
Since v4.0.0

Returns true when a value has the multipart part type identifier.

Details

This includes Field, File, and PersistedFile values. Use isStreamPart to identify only parsed, streamed parts.

Signature

declare function isPart(u: unknown): u is Part
Since v4.0.0

Returns true when a value is a persisted multipart file.

Signature

declare function isPersistedFile(u: unknown): u is PersistedFile
Since v4.0.0

Returns true when a value is a multipart text Field or streamed File.

Signature

declare function isStreamPart(u: unknown): u is Part

Models

Field

interface unstable
Since v4.0.0

Multipart form field containing a decoded text value.

Details

The key is the field name, contentType is the part media type, and value is the decoded field content.

Signature

interface Field extends Proto {
readonly _tag: "Field";
readonly contentType: string;
readonly key: string;
readonly value: string;
}

File

interface unstable
Since v4.0.0

Multipart file part.

Gotchas

The file content is exposed as a byte stream. contentEffect collects the full file into memory and should be used only when the file size is acceptable.

Signature

interface File extends Proto {
readonly _tag: "File";
readonly content: Stream<Uint8Array<ArrayBufferLike>, MultipartError>;
readonly contentEffect: Effect<Uint8Array<ArrayBufferLike>, MultipartError>;
readonly contentType: string;
readonly key: string;
readonly name: string;
}

Part

type unstable
Since v4.0.0

A parsed multipart part.

Details

A part is either a text Field or a streamed File.

Signature

type Part = Field | File

Persisted

interface unstable
Since v4.0.0

Record representation of persisted multipart data.

Details

Field names map to text values, arrays of text values, or arrays of PersistedFile values.

Signature

interface Persisted {
[key: string]: string | readonly Array<string> | readonly Array<PersistedFile>;
}

PersistedFile

interface unstable
Since v4.0.0

Multipart file part that has been written to the filesystem.

Details

The path points to the persisted file while the scope used to persist the multipart data remains open.

Signature

interface PersistedFile extends Proto {
readonly _tag: "PersistedFile";
readonly contentType: string;
readonly key: string;
readonly name: string;
readonly path: string;
}

Other

Part

unstable
Since v4.0.0

Namespace containing shared multipart part model types.

withLimits

unstable
Since v4.0.0

Namespace containing multipart parser limit option types.

Parsing

makeChannel

unstable
Since v4.0.0

Creates a channel that parses multipart byte chunks into multipart parts.

Details

The channel consumes non-empty batches of Uint8Array chunks and emits non-empty batches of parsed Part values, failing with MultipartError for parser and limit failures.

Signature

declare function makeChannel<IE>(headers: Record<string, string>): Channel<readonly [Part, Part], MultipartError | IE, void, readonly [Uint8Array<ArrayBufferLike>, Uint8Array<ArrayBufferLike>], IE, unknown>

References

Since v4.0.0

Creates a context containing multipart parser limit settings.

Details

The context can provide maximum part count, field size, file size, total body size, and MIME types that should be parsed as fields.

Signature

declare function limitsServices(options: {
readonly fieldMimeTypes?: readonly Array<string>;
readonly maxFieldSize?: Input;
readonly maxFileSize?: Input;
readonly maxParts?: number;
readonly maxTotalSize?: Input;
}): Context<never>

Schemas

FilesSchema

unstable
Since v4.0.0

Schema for an array of persisted multipart files.

Signature

declare const FilesSchema: Schema.$Array<PersistedFileSchema>
Since v4.0.0

Schema for persisted multipart files.

Details

The encoded form contains the field key, original file name, content type, and filesystem path.

Signature

declare const PersistedFileSchema: PersistedFileSchema

PersistedFileSchema

interface unstable
Since v4.0.0

Schema type for persisted multipart files.

Signature

interface PersistedFileSchema extends declare<PersistedFile> {
constructor(_: never);
}

schemaJson

unstable
Since v4.0.0

Creates a decoder for a JSON-encoded field in persisted multipart data.

Details

The selected field is parsed from a JSON string and decoded with the supplied schema.

Signature

declare function schemaJson<A, RD>(schema: ConstraintDecoder<A, RD>, options?: ParseOptions & JsonOptions): {
(field: string): (persisted: Persisted) => Effect<A, SchemaError, RD>;
(persisted: Persisted, field: string): Effect<A, SchemaError, RD>;
}
Since v4.0.0

Creates a decoder for persisted multipart data using the supplied schema.

Details

The returned function decodes an unknown input into the schema output and fails with SchemaError when validation fails.

Signature

declare function schemaPersisted<A, I extends Partial<Persisted>, RD>(schema: ConstraintCodec<A, I, RD, unknown>): (input: unknown, options?: ParseOptions) => Effect<A, SchemaError, RD>
Since v4.0.0

Schema for exactly one persisted multipart file.

Details

The encoded form is a one-element file array, while the decoded value is the single PersistedFile.

Signature

declare const SingleFileSchema: Schema.decodeTo<PersistedFileSchema, Schema.$Array<PersistedFileSchema>>

Services

Since v4.0.0

Context reference for MIME type fragments that should be parsed as multipart fields instead of files.

Details

The default treats application/json parts as fields.

Signature

declare const FieldMimeTypes: Reference<readonly Array<string>>
Since v4.0.0

Context reference for the maximum size of a multipart field value.

Details

The default limit is 10 MiB.

Signature

declare const MaxFieldSize: Reference<ByteSize>

MaxFileSize

unstable
Since v4.0.0

Context reference for the maximum size of a multipart file part.

Details

The default is undefined, meaning no explicit per-file limit.

Signature

declare const MaxFileSize: Reference<ByteSize | undefined>

MaxParts

unstable
Since v4.0.0

Context reference for the maximum number of multipart parts allowed.

Details

The default is undefined, meaning no explicit part-count limit.

Signature

declare const MaxParts: Reference<number | undefined>

Type IDs

TypeId

unstable
Since v4.0.0

Type identifier used to brand multipart part values.

Signature

declare const TypeId: "~effect/http/Multipart"