NousResearch/hermes-agent · warning · Error

Invalid PDF data URL

Error message

Invalid PDF data URL

What it means

First guard in dataUrlToBlob (preview-file.tsx) which converts a PDF data URL into a Blob for in-app preview. It requires the string to start with the literal 'data:' prefix and contain a comma separating metadata from payload. Missing either means the input is not a data URL at all (e.g. a plain URL, a file path, or a truncated/garbled payload), so the parser refuses it before inspecting the media type.

Source

Thrown at apps/desktop/src/app/chat/right-rail/preview-file.tsx:226

  for (const byte of bytes.slice(0, 4096)) {
    if (byte === 0) {
      return true
    }

    if (byte < 32 && byte !== 9 && byte !== 10 && byte !== 13) {
      suspicious += 1
    }
  }

  return suspicious / Math.min(bytes.length, 4096) > 0.12
}

function dataUrlToBlob(dataUrl: string) {
  const comma = dataUrl.indexOf(',')

  if (comma < 0 || !dataUrl.startsWith('data:')) {
    throw new Error('Invalid PDF data URL')
  }

  const metadata = dataUrl
    .slice(5, comma)
    .split(';')
    .map(part => part.trim().toLowerCase())

  const payload = dataUrl.slice(comma + 1)

  if (metadata[0] !== 'application/pdf' || !metadata.slice(1).includes('base64')) {
    throw new Error('Invalid PDF data URL type')
  }

  let binary: string

  try {
    binary = atob(decodeURIComponent(payload))
  } catch {

View on GitHub (pinned to c896c09c42)

Solutions

  1. Route only genuine data: URLs (application/pdf;base64,...) into dataUrlToBlob; branch on startsWith('data:') earlier in the caller.
  2. If the source is an http URL or file path, use the corresponding preview loader instead of the data-URL one.
  3. Fix the upstream producer so the comma and base64 payload are not double-encoded.
  4. DecodeURIComponent the candidate before this check if your pipeline URL-encodes data URLs.

Example fix

// before
function dataUrlToBlob(dataUrl: string) {
  const comma = dataUrl.indexOf(',')
  if (comma < 0 || !dataUrl.startsWith('data:')) {
    throw new Error('Invalid PDF data URL')
  }
  // ...
}

// after — normalize an encoded data URL before validating
function dataUrlToBlob(rawInput: string) {
  const dataUrl = rawInput.includes('%2C') ? decodeURIComponent(rawInput) : rawInput
  const comma = dataUrl.indexOf(',')
  if (comma < 0 || !dataUrl.startsWith('data:')) {
    throw new Error('Invalid PDF data URL')
  }
  // ...
}
Defensive patterns

Strategy: type-guard

Validate before calling

const looksLikeDataUrl = (s: string) => /^data:[^,]*,/i.test(s)
if (!looksLikeDataUrl(candidate)) {
  routeToNonDataUrlPreview(candidate) // http/file/blob path
}

Type guard

const isPdfDataUrl = (s: string): boolean => /^data:application\/pdf;base64,/i.test(s)

Try / catch

try {
  const blob = dataUrlToBlob(dataUrl)
} catch (error) {
  if (error instanceof Error && error.message.startsWith('Invalid PDF data URL')) {
    // fall back to download/raw display rather than failing the whole preview
  } else throw error
}

Prevention

When it happens

Trigger: Calling the PDF preview path with a value that is not a data URL: an http(s) URL to a PDF, a local file path, a blob: URL, or a data URL whose comma was stripped by URL encoding/trimming upstream.

Common situations: Tool results or attachment metadata carrying a remote PDF URL being routed into the data-URL preview branch; copy/paste truncation; an upstream step that encodeURIComponent'd the whole data URL so the comma became %2C.

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/a9e408769f2d1bbe. Report an issue: GitHub.