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

  1. Remove flagged content (embedded binaries, EICAR strings, obfuscated payloads) from the skill body and retry.
  2. 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.
  3. 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

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


AI-assisted analysis of Significant-Gravitas/AutoGPT@9c8bb5550f (2026-08-14). Data as JSON: /api/errors/19b03bad679de4b8. Report an issue: GitHub.