toeverything/AFFiNE · error · BlockSuiteError
ParsingError
ParsingError
Error message
Unsupported file type
What it means
After a file is chosen, importMindmap (import-mindmap.ts:21-29) only accepts FreeMind .mm files and .opml/.xml outlines; any other extension throws ParsingError 'Unsupported file type'. The check is by filename extension only, so a mismatched payload renamed to .mm will pass this check and fail later in parsing.
Solutions
- Pre-check the extension before calling importMindmap and show a friendly 'Supported: .mm, .opml, .xml' message
- Set the picker's accept filter to .mm,.opml,.xml if the file-dialog API supports it
- Normalize with file.name.toLowerCase().endsWith(...) before dispatching to a parser
Example fix
// before
const mindmap = await importMindmap(bound); // picks notes.txt -> ParsingError
// after
const name = file.name.toLowerCase();
if (!name.endsWith('.mm') && !name.endsWith('.opml') && !name.endsWith('.xml')) {
toast('Unsupported file type. Use .mm, .opml or .xml.');
return;
} Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED = ['.mm', '.opml', '.xml'] as const;
const isSupportedMindmapFile = (file: File): boolean => {
const name = file.name.toLowerCase();
return SUPPORTED.some(ext => name.endsWith(ext));
};
if (!isSupportedMindmapFile(file)) {
toast('Unsupported file type. Use .mm, .opml or .xml.');
return;
} Type guard
function isSupportedMindmapFile(file: File): boolean {
const n = file.name.toLowerCase();
return n.endsWith('.mm') || n.endsWith('.opml') || n.endsWith('.xml');
} Try / catch
try {
const mindmap = await importMindmap(bound);
} catch (e) {
if (e instanceof BlockSuiteError && e.code === BlockSuiteError.ErrorCode.ParsingError) {
toast('Unsupported file type. Use .mm, .opml or .xml.');
return;
}
throw e;
} Prevention
- Set the file picker accept filter to .mm,.opml,.xml where the dialog API allows
- Check extensions case-insensitively before calling importMindmap
- Tell users the supported formats in the import UI up front
When it happens
Trigger: User selects .xlsx/.md/.json or an extension-less export in the mindmap import picker; browsers/platforms that do not enforce the accept filter; files with trailing spaces or unusual case in the extension (endsWith is case-sensitive, so '.MM' also throws).
Common situations: File picker accept filter missing or ignored by the OS dialog; users trying to import OPML variants with uncommon extensions; case-sensitive extension mismatch on macOS/Windows exports.
Related errors
- image_format_not_supported
- invalid_app_config_input
- UserAbortError
- -32001
- A config file path is required
AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18).
Data as JSON: /api/errors/2495439a3e4c3ccd.
Report an issue: GitHub.
Appendix: source
Thrown at blocksuite/affine/gfx/mindmap/src/toolbar/utils/import-mindmap.ts:28
title?: string;
layoutType?: 'left' | 'right';
};
export async function importMindmap(bound: Bound): Promise<MindMapNode> {
const file = await openSingleFileWith('MindMap');
if (!file) {
throw new BlockSuiteError(ErrorCode.UserAbortError, 'Aborted by user');
}
let result;
if (file.name.endsWith('.mm')) {
result = await parseMmFile(file);
} else if (file.name.endsWith('.opml') || file.name.endsWith('.xml')) {
result = await parseOPMLFile(file);
} else {
throw new BlockSuiteError(ErrorCode.ParsingError, 'Unsupported file type');
}
if (result) {
result.xywh = bound.serialize();
}
return result;
}
function readAsText(file: File) {
return file.text();
}
type RawMmNode = {
node?: {
TEXT: string;
POSITION: 'left' | 'right';
children?: RawMmNode[];View on GitHub (pinned to b4c8548c09)