{"record":{"id":"ca11b37a61c568b3","repo":"binary-husky/gpt_academic","slug":"no-read-permission-path-ca11b3","errorCode":null,"errorMessage":"No read permission: {path}","messagePattern":"No read permission: (.+?)","errorType":"exception","errorClass":"PermissionError","httpStatus":null,"severity":"error","filePath":"crazy_functions/doc_fns/read_fns/unstructured_all/unstructured_reader.py","lineNumber":121,"sourceCode":"            max_size_mb: 允许的最大文件大小(MB)\n\n        Returns:\n            Path: 验证后的Path对象\n\n        Raises:\n            ValueError: 文件不存在、格式不支持或大小超限\n            PermissionError: 没有读取权限\n        \"\"\"\n        path = Path(file_path).resolve()\n\n        if not path.exists():\n            raise ValueError(f\"File not found: {path}\")\n\n        if not path.is_file():\n            raise ValueError(f\"Not a file: {path}\")\n\n        if not os.access(path, os.R_OK):\n            raise PermissionError(f\"No read permission: {path}\")\n\n        file_size_mb = path.stat().st_size / (1024 * 1024)\n        if file_size_mb > max_size_mb:\n            raise ValueError(\n                f\"File size ({file_size_mb:.1f}MB) exceeds limit of {max_size_mb}MB\"\n            )\n\n        if path.suffix.lower() not in self.SUPPORTED_EXTENSIONS:\n            raise ValueError(\n                f\"Unsupported format: {path.suffix}. \"\n                f\"Supported: {', '.join(sorted(self.SUPPORTED_EXTENSIONS))}\"\n            )\n\n        return path\n\n    def _cleanup_text(self, text: str) -> str:\n        \"\"\"清理文本\n","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/crazy_functions/doc_fns/read_fns/unstructured_all/unstructured_reader.py#L103-L139","documentation":"UnstructuredReader's English counterpart of the permission check: raised when os.access(path, os.R_OK) is False even though the file exists. Mirrors paper_metadata_extractor's Chinese variant so both readers behave identically.","triggerScenarios":"Same as the Chinese variant: file present, is_file() true, but the effective UID/GID lacks read permission — chmod 600 owned by another user, restrictive ACL, files created by a root process, or root_squash on NFS denying root readers.","commonSituations":"Multi-user deployments where uploads are owned by the web user but analysis runs under a worker user; Docker containers with mismatched UID; SELinux/AppArmor denials that manifest as EACCES; files restored from an archive with 000 mode.","solutions":["chmod a+r or chown the file to the service user, then retry.","Align UIDs between the container/process and the volume owner (docker run -u, user: in compose).","Check ACLs (getfacl) and SELinux context (ls -Z) when plain chmod doesn't help.","Copy the file to a process-owned temp dir before reading if permissions cannot be changed."],"exampleFix":"# before\ntext = reader.read('/srv/secure/paper.pdf')  # PermissionError\n\n# after\nimport shutil, tempfile\nif not os.access(p, os.R_OK):\n    tmp = Path(tempfile.mkdtemp()) / Path(p).name\n    shutil.copy(p, tmp)  # run where rights exist, or pre-fix modes\n    p = tmp\ntext = reader.read(p)","handlingStrategy":"validation","validationCode":"import os\nif not os.access(os.path.realpath(fp), os.R_OK):\n    fix_perms_or_copy_to_tmp(fp)","typeGuard":"def readable(path: str) -> bool:\n    import os\n    return os.path.isfile(path) and os.access(path, os.R_OK)","tryCatchPattern":"try:\n    reader.read(fp)\nexcept PermissionError as e:\n    log_warning(f'no read access: {e}')\n    skip_file(fp)","preventionTips":["Align container UID with volume ownership.","chmod at file creation (0o644).","Check getfacl/SELinux when chmod fails.","Copy protected inputs to a process-owned temp dir."],"tags":["filesystem","permissions","validation","python"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}