odysseus-dev/odysseus · warning · Error
Server error ' + res.status
Error message
Server error ' + res.status
What it means
HTTP 404 from PUT /{file_id}/vision when the caller is authenticated but neither the file's owner nor an admin — the owner-or-admin gate on the write path. Returned as 404 to avoid leaking other users' files. It is the second 404 on this route: the first (index miss) fires earlier, so reaching this one means the file exists in uploads.json but belongs to someone else.
Source
Thrown at static/js/chat.js:6266
}
}
if (!msgIds.length || !sessionId) {
// No persisted rows to delete (no DB IDs, or no session at all — e.g. an
// error output shown before a model was selected, #1428). Just remove the
// DOM so the "x" works regardless.
domToRemove.forEach(el => el.remove());
if (uiModule) uiModule.showToast('Message deleted');
return;
}
try {
const res = await fetch(`${API_BASE}/api/session/${sessionId}/delete-messages`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ msg_ids: msgIds })
});
if (!res.ok) throw new Error('Server error ' + res.status);
domToRemove.forEach(el => el.remove());
if (uiModule) uiModule.showToast('Message deleted');
} catch (err) {
console.error('Delete failed:', err);
if (uiModule) uiModule.showError('Delete failed: ' + err.message);
}
}
/**
* Edit an AI message inline. Makes the body contentEditable, saves to DB on confirm.
*/
export async function editAIMessage(msgElement) {
const body = msgElement.querySelector('.body');
if (!body) return;
const isEditing = body.contentEditable === 'true' || body.contentEditable === 'plaintext-only';
if (isEditing) return; // already editing
View on GitHub (pinned to f9235ebbf1)
Solutions
- Save the OCR edit from the owning account (or an admin) — the UI should only expose the editor to the owner.
- Inspect uploads.json to confirm the owner if access should have worked; repair misattributed ownership after user renames/migrations.
- Return a clear 'read-only' state in the UI for files the current user doesn't own to prevent the failed save.
Defensive patterns
Strategy: validation
Validate before calling
const canEdit = (att, user) => !authConfigured || att.owner === user || user?.isAdmin; if (!canEdit(att, currentUser)) renderReadOnly(att);
Try / catch
const r = await fetch(url, { method: 'PUT', credentials: 'include' });
if (r.status === 404) showNotEditable(att); // not owner — hide editor Prevention
- Only render the OCR editor for files the current user owns
- After account switches in shared browsers, refresh attachment ownership state
When it happens
Trigger: PUT /api/upload/{id}/vision as user B for a file whose index entry has owner=user A and B is not admin; ownership field changed by a migration so the editor no longer matches.
Common situations: Shared workstation/browser profile logged in as a different account; admin edited the file earlier, then a non-admin account tries to save over that edit.
Related errors
- HTTP ' + r.status
- Stream closed before completion
- Skill is not available for slash invocation
- d.error || 'Failed to create calendar'
- await res.text()
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/70bc4532bdec2d33.
Report an issue: GitHub.