{"record":{"id":"19b03bad679de4b8","repo":"Significant-Gravitas/AutoGPT","slug":"skill-content-rejected-by-virus-scan","errorCode":null,"errorMessage":"Skill content rejected by virus scan","messagePattern":"Skill content rejected by virus scan","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"autogpt_platform/backend/backend/api/features/v1.py","lineNumber":2695,"sourceCode":"            detail=(\n                \"File is not a valid SKILL.md — expected YAML frontmatter with \"\n                \"'name' and 'description' followed by a markdown body.\"\n            ),\n        )\n    try:\n        stored = await store_user_skill(\n            user_id,\n            name=parsed.name,\n            description=parsed.description,\n            body=parsed.body,\n            triggers=list(parsed.triggers),\n            version=parsed.version,\n        )\n    except SkillLimitError as exc:\n        raise HTTPException(status_code=409, detail=str(exc))\n    except (VirusDetectedError, VirusScanError) as exc:\n        logger.warning(\"[skills] virus scan rejected uploaded skill: %s\", exc)\n        raise HTTPException(\n            status_code=400, detail=\"Skill content rejected by virus scan\"\n        )\n    except ValueError as exc:\n        raise HTTPException(status_code=400, detail=str(exc))\n    return CopilotSkillInfo(\n        name=stored.name,\n        description=stored.description,\n        triggers=list(stored.triggers),\n    )\n\n\n@v1_router.get(\n    path=\"/skills/{name}\",\n    summary=\"Read a single copilot skill with its full SKILL.md body\",\n    operation_id=\"readCopilotSkill\",\n    tags=[\"skills\"],\n    responses={404: {\"description\": \"Skill not found\"}},\n    dependencies=[Security(requires_user)],","sourceCodeStart":2677,"sourceCodeEnd":2713,"githubUrl":"https://github.com/Significant-Gravitas/AutoGPT/blob/9c8bb5550f446ba5d3046b78896578742495b3cf/autogpt_platform/backend/backend/api/features/v1.py#L2677-L2713","documentation":"Skill-upload returns 400 when the ClamAV-backed virus scan of the skill content raises VirusDetectedError or VirusScanError during `store_user_skill`. Both are collapsed into the same generic client message and logged server-side (logger.warning '[skills] virus scan rejected uploaded skill') so scan details are not leaked. VirusScanError also fires when the scanner itself fails (unreachable ClamAV), not only on actual detections.","triggerScenarios":"POST upload of a SKILL.md whose body/frontmatter contains signatures ClamAV flags (EICAR test strings, embedded malicious payloads), or — for VirusScanError — uploads while the ClamAV service is down/misconfigured.","commonSituations":"Testing the upload pipeline with EICAR test files; embedding base64 blobs or scripts in skill bodies that trip heuristics; local dev stacks where the clamav docker service isn't started, making every upload fail with this 400.","solutions":["Remove flagged content (embedded binaries, EICAR strings, obfuscated payloads) from the skill body and retry.","If ALL uploads fail, check ClamAV health: `docker compose ps clamav` / `echo PING | nc localhost 3310`, and inspect server logs for the '[skills] virus scan' warning with the underlying exception.","Operators: ensure the clamav container is up and reachable before diagnosing content issues."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await api.uploadSkill(content);\n} catch (e) {\n  if (e.status === 400 && /virus scan/i.test(e.detail)) {\n    show('Content rejected by virus scan — remove embedded binaries/scripts.');\n    return;\n  }\n  throw e;\n}","preventionTips":["Keep skill bodies to plain markdown; avoid embedded binaries or base64 payloads.","Never use EICAR strings in real uploads — test with a dedicated sandbox flag instead.","If every upload is rejected, suspect ClamAV availability and check the service before blaming content."],"tags":["http-400","clamav","virus-scan","skills","security"],"backgroundTag":null,"analyzedSha":"9c8bb5550f446ba5d3046b78896578742495b3cf","analyzedAt":"2026-08-14T17:17:21.957Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}