binary-husky/gpt_academic · error · FriendlyException

输入文件的路径 ({path_or_url}) 存在,但位置非法。请将文件上传后再执行该任务。

Error message

输入文件的路径 ({path_or_url}) 存在,但位置非法。请将文件上传后再执行该任务。

What it means

FastAPI layer's path validation (_check_path_at_legal_server_side): after normalizing to a relative path, only three roots are allowed — PATH_LOGGING, PATH_PRIVATE_UPLOAD, and tests/build. Any existing file outside these roots (e.g. /etc/passwd or an arbitrary repo file) raises FriendlyException telling the user to upload the file first. It is an anti-arbitrary-file-read guard for the API server.

Source

Thrown at shared_utils/fastapi_server.py:63

"""

import os, requests, threading, time
import uvicorn

def validate_path_safety(path_or_url, user):
    from toolbox import get_conf, default_user_name
    from toolbox import FriendlyException
    PATH_PRIVATE_UPLOAD, PATH_LOGGING = get_conf('PATH_PRIVATE_UPLOAD', 'PATH_LOGGING')
    sensitive_path = None
    path_or_url = os.path.relpath(path_or_url)
    if path_or_url.startswith(PATH_LOGGING):    # 日志文件(按用户划分)
        sensitive_path = PATH_LOGGING
    elif path_or_url.startswith(PATH_PRIVATE_UPLOAD):   # 用户的上传目录(按用户划分)
        sensitive_path = PATH_PRIVATE_UPLOAD
    elif path_or_url.startswith('tests') or path_or_url.startswith('build'):   # 一个常用的测试目录
        return True
    else:
        raise FriendlyException(f"输入文件的路径 ({path_or_url}) 存在,但位置非法。请将文件上传后再执行该任务。") # return False
    if sensitive_path:
        allowed_users = [user, 'autogen', 'arxiv_cache', default_user_name]  # three user path that can be accessed
        for user_allowed in allowed_users:
            if f"{os.sep}".join(path_or_url.split(os.sep)[:2]) == os.path.join(sensitive_path, user_allowed):
                return True
        raise FriendlyException(f"输入文件的路径 ({path_or_url}) 存在,但属于其他用户。请将文件上传后再执行该任务。") # return False
    return True

def _authorize_user(path_or_url, request, gradio_app):
    from toolbox import get_conf, default_user_name
    PATH_PRIVATE_UPLOAD, PATH_LOGGING = get_conf('PATH_PRIVATE_UPLOAD', 'PATH_LOGGING')
    sensitive_path = None
    path_or_url = os.path.relpath(path_or_url)
    if path_or_url.startswith(PATH_LOGGING):
        sensitive_path = PATH_LOGGING
    if path_or_url.startswith(PATH_PRIVATE_UPLOAD):
        sensitive_path = PATH_PRIVATE_UPLOAD
    if sensitive_path:

View on GitHub (pinned to d6bde0fa54)

Solutions

  1. Upload the file through the API/WebUI so it lands under PATH_PRIVATE_UPLOAD/<user>/ and pass that path.
  2. Reference files under the tests/ or build/ directory if you genuinely need repo-local fixtures.
  3. For log-derived files, use paths under PATH_LOGGING belonging to your user.

Example fix

# before
curl -X POST .../v1/api/chat -d '{"input_file": "/etc/passwd"}'

# after
curl -X POST .../v1/api/upload -F 'file=@doc.pdf'   # then pass returned private-upload path
Defensive patterns

Strategy: validation

Validate before calling

import os
from toolbox import get_conf, default_user_name
PATH_PRIVATE_UPLOAD, PATH_LOGGING = get_conf('PATH_PRIVATE_UPLOAD', 'PATH_LOGGING')

def path_is_api_legal(p: str, user: str) -> bool:
    rp = os.path.relpath(p)
    return (rp.startswith(PATH_LOGGING) or rp.startswith(PATH_PRIVATE_UPLOAD)
            or rp.startswith('tests') or rp.startswith('build'))

if not path_is_api_legal(input_file, user):
    input_file = upload_file_first(input_file)  # route through the upload API

Try / catch

try:
    run_api_task(input_file=...)
except FriendlyException as e:
    if '位置非法' in str(e):
        uploaded = upload_and_get_private_path(local_file)
        run_api_task(input_file=uploaded)

Prevention

When it happens

Trigger: Calling an API endpoint that takes a file path with a path outside the allowed roots; e.g. POST /v1/api/... with input_file pointing at a system file or a project source file instead of something under the per-user upload or logging directory.

Common situations: Scripting against the fastapi_server with absolute local paths; porting curl examples from local CLI usage to the served API; attempting path traversal ('..') which normalizes outside the roots and hits this branch.

Related errors


AI-assisted analysis of binary-husky/gpt_academic@d6bde0fa54 (2026-08-14). Data as JSON: /api/errors/614296aea70f39e0. Report an issue: GitHub.