harry0703/MoneyPrinterTurbo · warning · ValueError

{description} file must exist inside {resource_dir}: {raw_pa

Error message

{description} file must exist inside {resource_dir}: {raw_path}

What it means

Raised by the stricter CLI resource resolver: it searches the file under the resource directory (and repo root), then accepts it only if the resolved real path both exists as a file and is contained within resource_dir (via the commonpath check, which also rejects symlink escapes). No candidate matched, so the file is not a valid in-resource asset.

Source

Thrown at cli.py:641

    """解析项目资源文件,并确保绝对路径仍位于对应资源目录内。"""
    from app.utils import utils

    expanded_path = os.path.expanduser(raw_path.strip())
    candidates = (
        [expanded_path]
        if os.path.isabs(expanded_path)
        else [
            os.path.join(resource_dir, expanded_path),
            os.path.join(utils.root_dir(), expanded_path),
        ]
    )
    for candidate in candidates:
        resolved_path = os.path.realpath(candidate)
        if os.path.isfile(resolved_path) and _path_is_within_directory(
            resolved_path, resource_dir
        ):
            return resolved_path
    raise ValueError(
        f"{description} file must exist inside {resource_dir}: {raw_path}"
    )


def prepare_cli_files(params: VideoParams, stop_at: str) -> None:
    """
    在调用 LLM/TTS 前准备 CLI 文件,避免长流程运行到后期才报告路径错误。

    服务层为了保护 API 请求,只允许读取 ``storage/local_videos`` 内的素材。
    CLI 是本地入口,接受当前目录相对路径和绝对路径。目录外素材会
    复制到受控目录,再把参数替换为服务层可安全使用的绝对路径。
    """
    from app.models import const
    from app.services import bgm as bgm_service
    from app.utils import utils

    local_material_extensions = {
        *(f".{extension}" for extension in const.FILE_TYPE_VIDEOS),

View on GitHub (pinned to 1f9f19c202)

Solutions

  1. Place the asset inside the expected resource directory and pass the relative name.
  2. Verify the file exists there: the resolver checks <resource_dir>/<name> then <repo_root>/<name>.
  3. Remove symlinks inside the resource dir that point outside — realpath-based containment rejects them.

Example fix

# before
python cli.py --font /home/user/fonts/custom.ttf

# after  # e.g. put the font under the resource dir
cp /home/user/fonts/custom.ttf resource/fonts/
python cli.py --font custom.ttf
Defensive patterns

Strategy: validation

Validate before calling

import os

def resource_file_exists(resource_dir: str, raw: str) -> bool:
    for base in (resource_dir, utils_root_dir()):
        cand = os.path.realpath(os.path.join(base, os.path.expanduser(raw)))
        if os.path.isfile(cand):
            try:
                inside = os.path.commonpath([os.path.realpath(resource_dir), cand]) == os.path.realpath(resource_dir)
            except ValueError:
                inside = False
            if inside:
                return True
    return False

Prevention

When it happens

Trigger: Passing a font/subtitle/song asset path that lives outside the resource directory; passing an absolute path to a file elsewhere on disk; a file inside resource_dir that is a symlink to an external location; simple filename typo where the file is not in the resource dir at all.

Common situations: User points --font/--bgm at a personal file outside the bundled resource folder; resources were relocated between versions; symlinked resource used to work but now fails the containment check.

Related errors


AI-assisted analysis of harry0703/MoneyPrinterTurbo@1f9f19c202 (2026-08-14). Data as JSON: /api/errors/360fe6ba1dbc9ced. Report an issue: GitHub.