zylon-ai/private-gpt · error · ValueError

File input requires valid base64 encoded content

Error message

File input requires valid base64 encoded content

What it means

Pydantic field_validator error on FileArtifact.value: the string must pass _is_valid_base64 before the model is accepted. The API accepts inline files only as base64-encoded content, and any malformed encoding (wrong alphabet, bad padding, embedded whitespace/newlines not tolerated by the check) is rejected at request-validation time.

Source

Thrown at private_gpt/server/utils/artifact_input.py:73

    def to_binary(self) -> BinaryIO:
        """Convert to BinaryIO (legacy method)."""
        return self.to_binary_content().data


class FileArtifact(Artifact):
    """Input for base64 encoded files."""

    type: Literal["file"] = Field(
        default="file", description="Input type discriminator"
    )
    value: str = Field(..., description="Base64 encoded file content")

    @field_validator("value")
    @classmethod
    def validate_base64(cls, v: str) -> str:
        if not _is_valid_base64(v):
            raise ValueError("File input requires valid base64 encoded content")
        return v

    def extract_filename(self, fallback_name: str | None = None) -> str:
        return fallback_name or "uploaded_file"

    def to_binary_content(self, filename: str | None = None) -> BinaryContent:
        decoded = base64.b64decode(self.value)
        extracted_filename = self.extract_filename(filename)
        return BinaryContent(io.BytesIO(decoded), extracted_filename)


class UriArtifact(Artifact):
    """Input for remote URIs."""

    type: Literal["uri"] = Field(default="uri", description="Input type discriminator")
    value: str = Field(..., description="URI to download from")

    def extract_filename(self, fallback_name: str | None = None) -> str:

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Encode before sending: in JS `btoa(text)` / `await fileToBase64(file)`; in Python `base64.b64encode(data).decode()`.
  2. Strip any 'data:...;base64,' prefix before submitting: `value.split(',').pop()`.
  3. If the source is base64url (JWTs, signed URLs), convert: replace '-'->'+', '_'->'/', and re-pad to a multiple of 4 with '='.
  4. Remove newlines/whitespace: `value.replace(/\s/g, '')`.

Example fix

// before
{ type: 'file', value: rawFileText }
// after
{ type: 'file', value: btoa(rawFileText) }  // or await blobToBase64(fileBlob)
Defensive patterns

Strategy: validation

Validate before calling

function toBase64Payload(input: string): string {
  const cleaned = input.replace(/^data:[^,]*;base64,/, '').replace(/\s+/g, '');
  if (!/^[A-Za-z0-9+/]*={0,2}$/.test(cleaned)) throw new Error('not base64');
  return cleaned.padEnd(Math.ceil(cleaned.length / 4) * 4, '=');
}

Type guard

const isValidBase64 = (v: string): boolean =>
  /^[A-Za-z0-9+/]*={0,2}$/.test(v) && v.length % 4 === 0;

Prevention

When it happens

Trigger: POSTing a chat/context request with {"type": "file", "value": "<raw bytes or plain text>"}; base64 with missing '=' padding; base64url characters ('-', '_') if the validator uses standard alphabet validation; strings containing data-URI prefixes like 'data:text/plain;base64,...' or stray whitespace/newlines depending on _is_valid_base64's strictness.

Common situations: Frontends passing the raw file contents or a File object's toString(); copying base64 from JWTs (base64url) or URLs; data-URI prefixes left on drag-and-drop payloads; text editors stripping the final '=' padding; line-wrapped PEM-style base64 pasted as-is.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/444a59f920423157. Report an issue: GitHub.