zylon-ai/private-gpt · error · ValueError
Invalid system item in list (dict): {item}
Error message
Invalid system item in list (dict): {item} What it means
Raised by the /convert endpoint (convert_content) when the request body specifies an explicit reader that is not registered for the file's extension. The ReaderRegistry maps extensions to a set of available reader names; a mismatch between the requested reader and the extension's registry entry yields this 422 Unprocessable Entity.
Source
Thrown at private_gpt/chat/input_models.py:208
except Exception as e:
raise ValueError(f"Invalid system specification (dict): {system}") from e
# List: allow list of System / str / dict and convert+merge
if isinstance(system, list):
# Convert each item to System
converted: list[System] = []
for item in system:
if isinstance(item, System):
converted.append(item)
elif isinstance(item, TextBlock):
converted.append(System(text=item.text))
elif isinstance(item, str):
converted.append(System(text=item))
elif isinstance(item, dict):
try:
converted.append(System.model_validate(item))
except Exception as e:
raise ValueError(
f"Invalid system item in list (dict): {item}"
) from e
else:
raise ValueError(f"Invalid system item in list: {item}")
if not converted:
return System()
# Merge converted System objects into a single System
potential_system = converted[0]
for item in converted[1:]:
merged_text = None
if potential_system.text or item.text:
# concatenate texts with newline when both present
if potential_system.text and item.text:
merged_text = f"{potential_system.text}\n{item.text}"
else:
merged_text = potential_system.text or item.textView on GitHub (pinned to 4a030776a3)
Solutions
- Omit body.reader to let the service auto-select the default reader for the extension.
- Call the registry (or check the error's 'Valid readers' list) and use one of the names it reports for that extension.
- If a specific reader is expected but absent, install its optional dependency / enable the component so it registers.
Example fix
# before
POST /ingest/convert
{"input": {...csv...}, "reader": "pymupdf"}
# after
POST /ingest/convert
{"input": {...csv...}} # reader omitted -> auto-selected
# or
{"input": {...csv...}, "reader": "pandas_csv"} # a name from registry.get_reader_names('.csv') Defensive patterns
Strategy: validation
Validate before calling
// Fetch valid readers for the extension before requesting const valid = await api.readerNames(extension); // or cache from docs if (reader && !valid.includes(reader)) reader = undefined; // let server pick
Type guard
const readerIsValid = (reader, valid) => valid.includes(reader);
Try / catch
try { await api.convert({ input, reader }); }
catch (e) {
if (e.status === 422 && /not supported/.test(e.detail)) {
return api.convert({ input }); // retry without explicit reader
}
throw e;
} Prevention
- Default to omitting reader and let the server choose
- Pin reader names only after checking registry.get_reader_names() for the exact extension
- After upgrades, re-verify hardcoded reader names still exist
When it happens
Trigger: POST /ingest/convert (or equivalent) with body.reader set to a name that exists for a different extension or not at all, while the input filename extension resolves via get_extension(). E.g. sending reader='pymupdf' for a .csv input where only readers registered for csv are valid.
Common situations: Hardcoding a reader name across file types after a version upgrade renamed readers; copy-pasting a curl example with a reader from another extension; a reader plugin not installed (e.g. its optional dependency missing) so it never registers.
Related errors
- Invalid system specification (dict): {system}
- Invalid system item in list: {item}
- Invalid system specification: {system}
- 'oneOf' must be an array of schemas
- 'anyOf' must be an array of schemas
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/7088a5ac664f3cfc.
Report an issue: GitHub.