{"record":{"id":"18bb8081689835f9","repo":"zylon-ai/private-gpt","slug":"failed-to-extract-file-info","errorCode":null,"errorMessage":"Failed to extract file info","messagePattern":"Failed to extract file info","errorType":"exception","errorClass":"RuntimeError","httpStatus":500,"severity":"error","filePath":"private_gpt/components/ingest/ingest_helper.py","lineNumber":21,"sourceCode":"\nfrom llama_index.core.schema import BaseNode\n\nfrom private_gpt.components.ingest.metadata_helper import MetadataHelper\nfrom private_gpt.components.ingest.progress.errors import IngestionValidationErrors\nfrom private_gpt.components.ingest.utils import FileInfo, should_ignore_mime_mismatch\nfrom private_gpt.settings.settings import settings\nfrom private_gpt.utils.mime import is_magic_available\n\nlogger = logging.getLogger(__name__)\n\n\nclass IngestionHelper:\n    @staticmethod\n    def validate_file_info(\n        file_info: FileInfo,\n    ) -> tuple[list[str], list[str]]:\n        if not file_info:\n            raise RuntimeError(\"Failed to extract file info\")\n\n        errors = []\n        warnings = []\n\n        # Check if the file info has size\n        if file_info.file_size is None or file_info.file_size <= 0:\n            errors.append(IngestionValidationErrors.INVALID_FILE_SIZE)\n\n        # Check if the file info has extension\n        if not file_info.extension:\n            errors.append(IngestionValidationErrors.UNKNOWN_FILE_EXTENSION)\n\n        if is_magic_available() and not file_info.actual_mime_type:\n            errors.append(IngestionValidationErrors.UNKNOWN_FILE_EXTENSION)\n\n        if (\n            file_info.guest_mime_type\n            and file_info.actual_mime_type","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/ingest/ingest_helper.py#L3-L39","documentation":"RuntimeError from IngestionHelper.validate_file_info when the file_info argument is falsy — None, an empty object, or anything that fails the truthiness check. It is the first statement of a static method, so it fires before any size/extension validation and signals that upstream extraction (metadata probing of the uploaded file) never produced a FileInfo.","triggerScenarios":"Calling IngestionHelper.validate_file_info(file_info) with file_info=None or an empty FileInfo, e.g. when the file-metadata extraction step upstream returned nothing for a missing, unreadable, or zero-byte upload.","commonSituations":"Upload endpoints where the file metadata probe silently swallows exceptions and returns None; temp file deleted before validation; multipart form missing the file field; code paths that construct FileInfo only on success and pass an uninitialized variable otherwise.","solutions":["Fix the upstream step that produces FileInfo so it never returns None (raise on extraction failure instead)","Check the upload actually contains a readable, non-empty file before validation","Pass a fully populated FileInfo: file_size > 0 and a non-empty extension, or validation will continue flagging errors","Add a guard where FileInfo is built: if extraction fails, surface that error rather than forwarding None"],"exampleFix":"# before\nfile_info = extract_file_info(maybe_missing_upload)  # returns None\nerrors, warnings = IngestionHelper.validate_file_info(file_info)  # RuntimeError\n\n# after\nfile_info = extract_file_info(upload)\nif file_info is None:\n    raise ValueError('could not read upload metadata')\nerrors, warnings = IngestionHelper.validate_file_info(file_info)","handlingStrategy":"validation","validationCode":"if file_info is None or not file_info:\n    raise ValueError('file info missing: file metadata extraction failed or upload empty')","typeGuard":"def has_file_info(fi) -> TypeGuard[FileInfo]:\n    return bool(fi)","tryCatchPattern":"try:\n    errors, warnings = IngestionHelper.validate_file_info(file_info)\nexcept RuntimeError as e:\n    if 'Failed to extract file info' in str(e):\n        return error_response(400, 'could not read file metadata; re-upload the file')\n    raise","preventionTips":["Never let the FileInfo extraction step return None silently — raise there instead","Check the multipart upload contains a readable, non-empty file before processing","Initialize FileInfo variables to a sentinel and assert on it before validation"],"tags":["ingest","validation","file-upload","null-check"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}