Significant-Gravitas/AutoGPT · error · HTTPException
Skill content rejected by virus scan
Error message
Skill content rejected by virus scan
What it means
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.
Source
Thrown at autogpt_platform/backend/backend/api/features/v1.py:2695
detail=(
"File is not a valid SKILL.md — expected YAML frontmatter with "
"'name' and 'description' followed by a markdown body."
),
)
try:
stored = await store_user_skill(
user_id,
name=parsed.name,
description=parsed.description,
body=parsed.body,
triggers=list(parsed.triggers),
version=parsed.version,
)
except SkillLimitError as exc:
raise HTTPException(status_code=409, detail=str(exc))
except (VirusDetectedError, VirusScanError) as exc:
logger.warning("[skills] virus scan rejected uploaded skill: %s", exc)
raise HTTPException(
status_code=400, detail="Skill content rejected by virus scan"
)
except ValueError as exc:
raise HTTPException(status_code=400, detail=str(exc))
return CopilotSkillInfo(
name=stored.name,
description=stored.description,
triggers=list(stored.triggers),
)
@v1_router.get(
path="/skills/{name}",
summary="Read a single copilot skill with its full SKILL.md body",
operation_id="readCopilotSkill",
tags=["skills"],
responses={404: {"description": "Skill not found"}},
dependencies=[Security(requires_user)],View on GitHub (pinned to 9c8bb5550f)
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.
Defensive patterns
Strategy: try-catch
Try / catch
try {
await api.uploadSkill(content);
} catch (e) {
if (e.status === 400 && /virus scan/i.test(e.detail)) {
show('Content rejected by virus scan — remove embedded binaries/scripts.');
return;
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- url must point at a trusted frontend origin.
- Picker tokens are not available for provider '{provider.valu
- Username mismatch: authenticated as a different user
- Invalid signature
- name is required
AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14).
Data as JSON: /api/errors/19b03bad679de4b8.
Report an issue: GitHub.