zylon-ai/private-gpt · error · SkillDomainError
MISSING_FILES
MISSING_FILES
Error message
At least one file is required
What it means
SkillDomainError with code MISSING_FILES, thrown by stored_files_from_uploads when the uploads list is empty. The skills upload pipeline requires at least one UploadFile (or one zip containing files) to build a skill version. It is a domain-level guard, not a framework error, and typically surfaces as an HTTP 401-mapped error response.
Source
Thrown at private_gpt/server/skills/skills_files.py:46
if raw is None:
continue
filename, content_type = _infer_file_meta(k, raw)
uploads.append(
UploadFile(
file=BytesIO(raw),
filename=filename,
headers=Headers({"content-type": content_type}),
)
)
return uploads
async def stored_files_from_uploads(
uploads: list[UploadFile],
default_mime_type: str | None = "application/octet-stream",
) -> list[StoredFile]:
if not uploads:
raise SkillDomainError(
SkillErrorCode.MISSING_FILES, "At least one file is required"
)
resolved: dict[str, StoredFile] = {}
for upload in uploads:
payload = await upload.read()
if _is_zip(upload):
for path, content in _extract_zip(upload, payload):
normalized = _normalize_path(path)
resolved[normalized] = StoredFile(
path=normalized, content=content, mime_type=None
)
else:
name = _normalize_path(upload.filename or "")
resolved[name] = StoredFile(
path=name, content=payload, mime_type=upload.content_type
)View on GitHub (pinned to 4a030776a3)
Solutions
- Include at least one file part (typically a zip containing SKILL.md) in the multipart request.
- If invoking stored_files_from_uploads programmatically, guard with `if not uploads: return []` (or raise your own clearer error) before calling.
- Log the raw multipart body in a repro to confirm the file field name matches what the server expects.
Example fix
# before
files = await stored_files_from_uploads([]) # SkillDomainError
# after
if uploads:
files = await stored_files_from_uploads(uploads)
else:
raise HTTPException(422, 'Attach at least one file to the upload') Defensive patterns
Strategy: validation
Validate before calling
const form = new FormData();
// ...
if (![...form.keys()].some((k) => form.getAll(k).some((v) => v instanceof File))) {
throw new Error('Attach at least one file before submitting');
} Type guard
const hasFiles = (form: FormData): boolean =>
Array.from(form.getAll('files')).some((v) => v instanceof File && v.size >= 0); Prevention
- Disable the submit button until at least one file part is attached.
- Name the file field exactly what the endpoint expects and log the multipart keys in dev builds.
- Never call stored_files_from_uploads with a possibly-empty list without an explicit check.
When it happens
Trigger: Calling the multipart upload endpoint with no file parts at all, or a client that sends only form fields; also calling stored_files_from_uploads directly with an empty list (e.g. after filtering out zero-length parts upstream).
Common situations: HTML forms or scripts where the file input is optional and left blank; fetch/axios multipart bodies built from an empty array; test harnesses passing [] accidentally; upstream code dropping files due to size limits before the handler runs.
Related errors
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/451be854c2cb2fd3.
Report an issue: GitHub.