zylon-ai/private-gpt · error · ValueError
Invalid system item: {item}
Error message
Invalid system item: {item} What it means
Raised by GET /skills/{skill_id}/versions/{version} when the skill does not exist in the collection (first guard). The route verifies the parent skill before looking up the specific version token.
Source
Thrown at private_gpt/chat/input_models.py:1262
if value.get("type") == "text" and isinstance(value.get("text"), str):
return [System(text=value["text"])]
return [System.model_validate(value)]
if isinstance(value, list):
systems: list[System] = []
for item in value:
if isinstance(item, System):
systems.append(item)
elif isinstance(item, TextBlock):
systems.append(System(text=item.text))
elif isinstance(item, str):
systems.append(System(text=item))
elif isinstance(item, dict):
if item.get("type") == "text" and isinstance(item.get("text"), str):
systems.append(System(text=item["text"]))
else:
systems.append(System.model_validate(item))
else:
raise ValueError(f"Invalid system item: {item}")
return systems or [System()]
raise ValueError(f"Invalid system value: {value}")
@field_validator("model", mode="before")
@classmethod
def normalize_model(cls, value: str | None) -> str:
if value is None:
return "default"
return value
@model_validator(mode="after")
def extract_system_messages(self) -> "MessagesInputBase":
"""Extract role=system messages and append them to the system list."""
system_msgs = [msg for msg in self.messages if msg.role == "system"]
if not system_msgs:
return self
self.messages = [msg for msg in self.messages if msg.role != "system"]View on GitHub (pinned to 4a030776a3)
Solutions
- Confirm the skill exists first and handle 404 by falling back to the skill list.
- Re-fetch the version list for the skill to obtain valid tokens.
- Ensure the collection parameter matches the environment the token came from.
Example fix
// before
const v = await skillsApi.getVersion(id, version, col);
// after
const v = await skillsApi.getVersion(id, version, col).catch((e) => {
if (e.status === 404) return skillsApi.listVersions(id, col).then(() => null);
throw e;
}); Defensive patterns
Strategy: try-catch
Validate before calling
const skill = await skillsApi.get(id, collection).catch(() => null); if (!skill) throw new SkillGoneError(id);
Try / catch
try { return await skillsApi.getVersion(id, version, collection); }
catch (e) {
if (e.status === 404) { const l = await skillsApi.listVersions(id, collection); return l.data[0] ?? null; }
throw e;
} Prevention
- Check the skill exists before resolving version tokens
- Never persist version tokens across environments
- Fall back to the newest version when a token 404s
When it happens
Trigger: Fetching a version by token for a skill id that is deleted, in another collection, or invalid.
Common situations: Version-permalink clicked after the skill was removed; cached version tokens reused across environments.
Related errors
- Unknown message role {self.role}. Expected 'system', 'user',
- Unsupported content block type: {type(block)}
- Audio size {audio_size} exceeds maximum allowed size of {set
- Invalid tool specification: {tool}
- Invalid system value: {value}
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/8c00b7f9081c99d3.
Report an issue: GitHub.