hiyouga/LlamaFactory · error · ValueError

`adapter_folder` must stay inside the KT adapter directory.

Error message

`adapter_folder` must stay inside the KT adapter directory.

What it means

Raised by _resolve_kt_adapter_artifact_dir when adapter_folder resolves (after realpath) to a location outside the adapter root directory. The commonpath guard prevents path-traversal style folders like ../../elsewhere from redirecting KT's artifact lookup outside the declared adapter.

Source

Thrown at src/llamafactory/hparams/model_args.py:654

                "kt_activation_policy": self.get_kt_activation_policy(),
                "kt_train_mode": "lora",
                "kt_full_weight_grad": False,
            }
        )
        return {key: value for key, value in kt_config.items() if value is not None}

    def _resolve_kt_adapter_artifact_dir(self, operation: str) -> str | None:
        if not self.adapter_name_or_path:
            return None
        if len(self.adapter_name_or_path) != 1:
            raise ValueError("KTransformers accepts a single `adapter_name_or_path`.")

        adapter_root = os.path.realpath(os.path.expanduser(self.adapter_name_or_path[0]))
        adapter_dir = adapter_root
        if self.adapter_folder:
            adapter_dir = os.path.realpath(os.path.join(adapter_root, self.adapter_folder))
            if os.path.commonpath((adapter_root, adapter_dir)) != adapter_root:
                raise ValueError("`adapter_folder` must stay inside the KT adapter directory.")
        if not os.path.isdir(adapter_dir):
            raise ValueError(f"KTransformers {operation} requires a local adapter directory.")
        return adapter_dir

    def apply_kt_config(self, finetuning_args: Any, training_args: Any, model_max_length: int | None) -> None:
        r"""Apply LLaMA-Factory KT args to transformers/accelerate KT integration points."""
        if not self.use_kt:
            return

        self.configure_kt_checkpointing(training_args)
        kt_config = self.get_kt_config_dict(
            finetuning_args,
            model_max_length,
            self._get_advanced_kt_config(training_args),
        )
        update_kt_config = getattr(training_args, "update_kt_config", None)
        if not callable(update_kt_config):
            raise RuntimeError(

View on GitHub (pinned to f28afaf635)

Solutions

  1. Make `adapter_folder` a relative subfolder of the adapter root, e.g. `checkpoint-500`.
  2. Or drop `adapter_folder` and set `adapter_name_or_path` directly to the exact directory containing the adapter.

Example fix

# before (yaml)
adapter_name_or_path: saves/lora_v2
adapter_folder: ../../other_run/checkpoint-500

# after (yaml)
adapter_name_or_path: saves/lora_v2
adapter_folder: checkpoint-500
Defensive patterns

Strategy: validation

Validate before calling

import os
root = os.path.realpath(os.path.expanduser(cfg['adapter_name_or_path'][0]))
target = os.path.realpath(os.path.join(root, cfg.get('adapter_folder') or ''))
if os.path.commonpath((root, target)) != root:
    raise SystemExit('adapter_folder escapes the adapter directory')

Prevention

When it happens

Trigger: Setting adapter_name_or_path: /data/adapter together with adapter_folder: ../../other/checkpoint; os.path.commonpath of the resolved paths differs from the adapter root, so the guard fires.

Common situations: Users try to point adapter_folder at a checkpoint saved elsewhere on disk (e.g. a shared step-500 dir) instead of a subfolder of the adapter root.

Related errors


AI-assisted analysis of hiyouga/LlamaFactory@f28afaf635 (2026-08-14). Data as JSON: /api/errors/cb415f7da3c7ad5b. Report an issue: GitHub.