odysseus-dev/odysseus · error · Error
PDF import failed
Error message
PDF import failed
What it means
Thrown in the file-import handler of static/js/document.js when POST /api/documents/import-pdf (multipart with file and optional session_id) returns non-2xx. The static message 'PDF import failed' discards both the status and any JSON detail the backend provided.
Source
Thrown at static/js/document.js:9564
const ext = dotIdx >= 0 ? name.slice(dotIdx).toLowerCase() : '';
const baseTitle = dotIdx > 0 ? name.slice(0, dotIdx) : name;
const isSpreadsheet = ['.xlsx','.xls','.ods'].includes(ext);
const isPdf = ext === '.pdf';
// Spreadsheets need the library's per-sheet split — defer to it.
if (isSpreadsheet) {
openLibrary();
requestAnimationFrame(() => requestAnimationFrame(() => document.getElementById('doclib-import-file-btn')?.click()));
return;
}
try {
let docId = null;
if (isPdf) {
const fd = new FormData();
fd.append('file', file);
const sid = (sessionModule && sessionModule.getCurrentSessionId && sessionModule.getCurrentSessionId()) || _lastSessionId || '';
if (sid) fd.append('session_id', sid);
const r = await fetch(`${API_BASE}/api/documents/import-pdf`, { method: 'POST', body: fd, credentials: 'same-origin' });
if (!r.ok) throw new Error('PDF import failed');
const j = await r.json();
docId = j.doc_id || j.id;
} else {
const content = await new Promise((res, rej) => {
const reader = new FileReader();
reader.onload = () => res(reader.result || '');
reader.onerror = () => rej(reader.error);
reader.readAsText(file);
});
const lang = EXT_TO_LANG[ext] !== undefined ? EXT_TO_LANG[ext] : null;
const sid = (sessionModule && sessionModule.getCurrentSessionId && sessionModule.getCurrentSessionId()) || _lastSessionId || '';
const body = { title: baseTitle, language: lang, content };
if (sid) body.session_id = sid;
const r = await fetch(`${API_BASE}/api/document`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'same-origin',
body: JSON.stringify(body),View on GitHub (pinned to f9235ebbf1)
Solutions
- Retry with a small, unencrypted PDF to isolate parser vs. transport failure.
- Check response body for detail — encrypted or malformed PDFs are usually named there.
- Raise upload limits / timeouts if large PDFs fail with 413 or 504.
- Include status and detail in the message for diagnosability.
Example fix
// before
if (!r.ok) throw new Error('PDF import failed');
// after
if (!r.ok) {
let detail = '';
try { const j = await r.json(); detail = j?.detail || j?.error || ''; } catch (_) {}
throw new Error(`PDF import failed: HTTP ${r.status}${detail ? ` — ${detail}` : ''}`);
} Defensive patterns
Strategy: try-catch
Validate before calling
const isPdf = file.type === 'application/pdf' || file.name.toLowerCase().endsWith('.pdf');
if (isPdf && file.size > PDF_MAX_BYTES) { if (uiModule) uiModule.showError('PDF too large'); return; } Type guard
function isPdfImportResult(j) {
return j != null && typeof j === 'object' && Boolean(j.doc_id || j.id);
} Try / catch
try {
const r = await fetch(`${API_BASE}/api/documents/import-pdf`, { method: 'POST', body: fd, credentials: 'same-origin' });
if (!r.ok) {
let detail = '';
try { const j = await r.json(); detail = j?.detail || j?.error || ''; } catch (_) {}
throw new Error(`PDF import failed: HTTP ${r.status}${detail ? ' — ' + detail : ''}`);
}
const j = await r.json();
if (!isPdfImportResult(j)) throw new Error('PDF import returned no document id');
} catch (e) {
if (uiModule) uiModule.showError(e.message);
} Prevention
- Reject encrypted PDFs client-side (can't detect reliably — but warn on known-protected workflows).
- Match client size caps to the server's multipart limit.
- Always pass credentials and include the backend detail in the thrown message.
When it happens
Trigger: Importing a PDF larger than the upload limit (413), corrupt/encrypted PDF rejected by the parser (400/422), server-side PDF library missing (500), or missing session_id causing a validation error.
Common situations: Dragging a password-protected or scanner-corrupted PDF onto the editor; oversized PDFs behind nginx; backend deployed without pdf tooling.
Related errors
- PDF import failed: ${_e}
- (data && (data.error || data.detail)) || `HTTP ${res.status}
- Failed
- Import failed
- res.statusText
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/9553b48683ef8d8f.
Report an issue: GitHub.