odysseus-dev/odysseus · error · Error
Server did not return a session id
Error message
Server did not return a session id
What it means
Raised by _fetch_bytes when a downloaded file's content length exceeds MAX_FILE_BYTES (400,000 bytes, ~400 KB). Every raw-asset fetch in the importer — SKILL.md itself, referenced files, and per-file downloads during directory traversal — goes through this single guard, so any one oversized file aborts the whole import.
Source
Thrown at src/visual_report.py:1096
if (chatBtn) {{
chatBtn.addEventListener('click', function() {{
var researchId = chatBtn.dataset.researchId;
if (!researchId) return;
var origLabel = chatBtn.innerHTML;
chatBtn.disabled = true;
chatBtn.innerHTML = '<span>Creating chat…</span>';
fetch('/api/research/spinoff/' + encodeURIComponent(researchId), {{
method: 'POST', credentials: 'same-origin',
}}).then(function(res) {{
if (!res.ok) {{
return res.json().then(function(d) {{
throw new Error(d && d.detail ? d.detail : ('HTTP ' + res.status));
}}, function() {{ throw new Error('HTTP ' + res.status); }});
}}
return res.json();
}}).then(function(data) {{
if (!data || !data.session_id) {{
throw new Error('Server did not return a session id');
}}
var url = '/#' + data.session_id;
var opened = false;
// The report typically opens in a new tab — if we have access to the
// original Odysseus tab, navigate it and close this report tab so the
// user lands directly in the new chat.
try {{
if (window.opener && !window.opener.closed) {{
window.opener.location.href = url;
window.opener.location.reload();
window.opener.focus();
opened = true;
window.close();
}}
}} catch (e) {{ /* cross-origin or detached opener — fall through */ }}
if (!opened) {{
// No opener (report was opened directly via URL) — open the chat in a
// new tab so the report stays available.View on GitHub (pinned to f9235ebbf1)
Solutions
- Move the oversized asset out of the skill folder and reference it by URL inside SKILL.md instead of shipping it in the bundle
- Split the large file into smaller pieces under 400 KB each, or trim it to what the skill actually needs
- If you control the importer and genuinely need bigger files, raise MAX_FILE_BYTES in services/memory/skill_importer.py:21 — but note the 2 MB MAX_TOTAL_BYTES bundle cap still applies
- Check for accidentally committed build artifacts (dist/, minified bundles, lock files) and remove them from the repo path
Example fix
# before my-skill/ SKILL.md big-dataset.json # 1.2 MB -> SkillImportError: file too large # after my-skill/ SKILL.md # references https://example.com/data/big-dataset.json
Defensive patterns
Strategy: validation
Validate before calling
import httpx
from services.memory.skill_importer import MAX_FILE_BYTES
async def fetch_if_small(url: str) -> bytes | None:
async with httpx.AsyncClient(follow_redirects=True) as c:
r = await c.head(url, follow_redirects=True)
size = int(r.headers.get("content-length") or 0)
if size and size > MAX_FILE_BYTES:
return None # skip before downloading
r = await c.get(url)
return r.content if len(r.content) <= MAX_FILE_BYTES else None Try / catch
try:
files, src = fetch_skill_bundle(url)
except SkillImportError as e:
if "file too large" in str(e):
report(f"{url}: an asset exceeds {MAX_FILE_BYTES} bytes — slim the skill folder or link assets by URL")
return None
raise Prevention
- Keep every bundled text asset under 400 KB; link large data by URL in SKILL.md
- Add a CI check on skill repos rejecting files > MAX_FILE_BYTES in skill folders
- HEAD-check content-length before downloading when building custom fetchers
When it happens
Trigger: A skill folder contains a single text asset (large CSV dataset, bundled JSON, long reference doc, minified JS) larger than 400 KB; fetch_skill_bundle downloads its download_url via _fetch_bytes and len(r.content) > 400000. Directly fetching an oversized SKILL.md from a /blob/... link hits the same check.
Common situations: Skills that bundle prompt libraries, embeddings, dictionaries, or generated reference data inline instead of linking out. Also common after a doc-generation step adds a huge auto-produced file next to SKILL.md.
Related errors
- d.detail || 'Failed'
- d && d.detail ? d.detail : ('HTTP ' + res.status)
- {context} must stay on GitHub (got {host or 'unknown host'})
- skills.sh did not redirect to GitHub — open the skill's repo
- Invalid raw GitHub URL
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/7810f0b32727ab91.
Report an issue: GitHub.