AykutSarac/jsoncrack.com · warning

Unable to load file ${files[0].file.name}

Error message

Unable to load file ${files[0].file.name}

What it means

Toast from the Mantine Dropzone onReject callback in the Import modal. onReject fires when the dropped/selected files fail validation: MIME type not in the accept list (application/json, application/x-yaml, text/csv, application/xml), or more than maxFiles (1) are dropped. files[0].file.name is the rejected file's name.

Source

Thrown at apps/www/src/features/modals/ImportModal/index.tsx:71

      onClose={() => {
        setFile(null);
        setURL("");
        onClose();
      }}
      centered
    >
      <Stack py="sm">
        <TextInput
          value={url}
          onChange={e => setURL(e.target.value)}
          type="url"
          placeholder="URL of JSON to fetch"
          data-autofocus
        />
        <Paper radius="md" style={{ cursor: "pointer" }}>
          <Dropzone
            onDrop={files => setFile(files[0])}
            onReject={files => toast.error(`Unable to load file ${files[0].file.name}`)}
            maxFiles={1}
            p="md"
            accept={["application/json", "application/x-yaml", "text/csv", "application/xml"]}
          >
            <Stack justify="center" align="center" gap="sm" mih={220}>
              <AiOutlineUpload size={48} />
              <Text fw="bold">Drop here or click to upload files</Text>
              <Text c="dimmed" fz="sm">
                {file?.name ?? "None"}
              </Text>
            </Stack>
          </Dropzone>
        </Paper>
      </Stack>
      <Group justify="right">
        <Button onClick={handleImportFile} disabled={!(file || url)}>
          Import
        </Button>

View on GitHub (pinned to 3c9af69e23)

Solutions

  1. Confirm the file's actual MIME type matches one of the accepted types before dropping.
  2. Drop files one at a time (maxFiles is 1).
  3. Widen the accept list in Dropzone if you legitimately need additional formats.
  4. Convert/save the file with a standard extension before importing.

Example fix

// before
accept={["application/json", "application/x-yaml", "text/csv", "application/xml"]}

// after — also accept common JSON/YAML extensions and text variants
accept={{
  "application/json": [".json"],
  "application/x-yaml": [".yaml", ".yml"],
  "text/csv": [".csv"],
  "application/xml": [".xml"],
  "text/plain": [".json", ".yaml", ".yml"],
}}
Defensive patterns

Strategy: validation

Validate before calling

// Verify MIME/extension against the accept list before dropping
const ACCEPTED = ["application/json", "application/x-yaml", "text/csv", "application/xml"];
export function isAccepted(file: File): boolean {
  return ACCEPTED.includes(file.type) || /\.(json|yaml|yml|csv|xml)$/i.test(file.name);
}

Type guard

// Narrow a Dropzone FileReject array
import type { FileRejection } from "@mantine/dropzone";
export function hasRejections(files: FileRejection[] | null): files is FileRejection[] {
  return Array.isArray(files) && files.length > 0;
}

Try / catch

// onReject is event-driven, not thrown; enrich the message
onReject={rejections =>
  toast.error(`Rejected: ${rejections.map(r => r.file.name).join(", ")}`)
}

Prevention

When it happens

Trigger: Dropping a .txt, .md, .xml with a non-listed MIME, a binary file, or multiple files at once. The Dropzone validates accept + maxFiles and routes failures to onReject rather than onDrop.

Common situations: File extension registered to a different MIME on the user's OS (e.g. a JSON file served/stored as text/plain); dropping a folder; trying to import a .json5 or .toml which is not in the accept list.

Related errors


AI-assisted analysis of AykutSarac/jsoncrack.com@3c9af69e23 (2026-08-12). Data as JSON: /api/errors/72fc66f59d6b091e. Report an issue: GitHub.