{"record":{"id":"8c00b7f9081c99d3","repo":"zylon-ai/private-gpt","slug":"invalid-system-item-item","errorCode":null,"errorMessage":"Invalid system item: {item}","messagePattern":"Invalid system item: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"private_gpt/chat/input_models.py","lineNumber":1262,"sourceCode":"            if value.get(\"type\") == \"text\" and isinstance(value.get(\"text\"), str):\n                return [System(text=value[\"text\"])]\n            return [System.model_validate(value)]\n        if isinstance(value, list):\n            systems: list[System] = []\n            for item in value:\n                if isinstance(item, System):\n                    systems.append(item)\n                elif isinstance(item, TextBlock):\n                    systems.append(System(text=item.text))\n                elif isinstance(item, str):\n                    systems.append(System(text=item))\n                elif isinstance(item, dict):\n                    if item.get(\"type\") == \"text\" and isinstance(item.get(\"text\"), str):\n                        systems.append(System(text=item[\"text\"]))\n                    else:\n                        systems.append(System.model_validate(item))\n                else:\n                    raise ValueError(f\"Invalid system item: {item}\")\n            return systems or [System()]\n        raise ValueError(f\"Invalid system value: {value}\")\n\n    @field_validator(\"model\", mode=\"before\")\n    @classmethod\n    def normalize_model(cls, value: str | None) -> str:\n        if value is None:\n            return \"default\"\n        return value\n\n    @model_validator(mode=\"after\")\n    def extract_system_messages(self) -> \"MessagesInputBase\":\n        \"\"\"Extract role=system messages and append them to the system list.\"\"\"\n        system_msgs = [msg for msg in self.messages if msg.role == \"system\"]\n        if not system_msgs:\n            return self\n\n        self.messages = [msg for msg in self.messages if msg.role != \"system\"]","sourceCodeStart":1244,"sourceCodeEnd":1280,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/chat/input_models.py#L1244-L1280","documentation":"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.","triggerScenarios":"Fetching a version by token for a skill id that is deleted, in another collection, or invalid.","commonSituations":"Version-permalink clicked after the skill was removed; cached version tokens reused across environments.","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."],"exampleFix":"// before\nconst v = await skillsApi.getVersion(id, version, col);\n\n// after\nconst v = await skillsApi.getVersion(id, version, col).catch((e) => {\n  if (e.status === 404) return skillsApi.listVersions(id, col).then(() => null);\n  throw e;\n});","handlingStrategy":"try-catch","validationCode":"const skill = await skillsApi.get(id, collection).catch(() => null);\nif (!skill) throw new SkillGoneError(id);","typeGuard":null,"tryCatchPattern":"try { return await skillsApi.getVersion(id, version, collection); }\ncatch (e) {\n  if (e.status === 404) { const l = await skillsApi.listVersions(id, collection); return l.data[0] ?? null; }\n  throw e;\n}","preventionTips":["Check the skill exists before resolving version tokens","Never persist version tokens across environments","Fall back to the newest version when a token 404s"],"tags":["fastapi","http-404","skills","versioning","not-found"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}