{"record":{"id":"11b2416aa2d386a3","repo":"odysseus-dev/odysseus","slug":"non-text-file-url","errorCode":null,"errorMessage":"non-text file: {url}","messagePattern":"non-text file: (.+?)","errorType":"validation","errorClass":"SkillImportError","httpStatus":null,"severity":"error","filePath":"services/memory/skill_importer.py","lineNumber":394,"sourceCode":"    return SkillImportError(f\"GitHub request failed ({status})\")\n\n\ndef _fetch_bytes(url: str) -> bytes:\n    r = _get_checked(url, headers={\"Accept\": \"application/vnd.github+json\"}, timeout=30.0)\n    if r.status_code >= 400:\n        raise _github_response_error(r)\n    _assert_github_url(str(r.url), context=\"redirect target\")\n    if len(r.content) > MAX_FILE_BYTES:\n        raise SkillImportError(f\"file too large: {url}\")\n    return r.content\n\n\ndef _fetch_text(url: str) -> str:\n    data = _fetch_bytes(url)\n    try:\n        return data.decode(\"utf-8\")\n    except UnicodeDecodeError as e:\n        raise SkillImportError(f\"non-text file: {url}\") from e\n\n\ndef _list_github_dir(src: ResolvedSource, rel_dir: str, out: Dict[str, str], *, depth: int = 0) -> None:\n    if depth > 4 or len(out) >= MAX_FILES:\n        return\n    url = _api_contents_url(src, rel_dir)\n    r = _get_checked(url, headers={\"Accept\": \"application/vnd.github+json\"}, timeout=30.0)\n    if r.status_code >= 400:\n        raise _github_response_error(r)\n    _assert_github_url(str(r.url), context=\"redirect target\")\n    entries = r.json()\n    if not isinstance(entries, list):\n        raise SkillImportError(\"expected a directory on GitHub\")\n    total = sum(len(v.encode(\"utf-8\")) for v in out.values())\n    for ent in entries:\n        if len(out) >= MAX_FILES or total >= MAX_TOTAL_BYTES:\n            break\n        if not isinstance(ent, dict):","sourceCodeStart":376,"sourceCodeEnd":412,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/services/memory/skill_importer.py#L376-L412","documentation":"Error \"non-text file: {url}\" thrown in odysseus-dev/odysseus.","triggerScenarios":"Triggered when the corresponding server-side validation or runtime check at the recorded location rejects the request or operation and returns this error message to the caller.","commonSituations":"See trigger scenarios.","solutions":["Remove binary or non-text files from the skill bundle.","Link only to text-based skill files (Markdown, code)."],"exampleFix":null,"handlingStrategy":null,"validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}