warpdotdev/warp · error · InspectionError
settings_symlink_rejected
settings_symlink_rejected
Error message
settings_symlink_rejected
What it means
_read_toml_object() refuses to follow symlinks: if the --source (GUI) or --destination (TUI) settings TOML is a symlink, it raises settings_symlink_rejected before reading a byte. This is deliberate — following a link could read or write outside the managed settings area, and the script's sanitized errors must not depend on where a link points.
Source
Thrown at resources/bundled/skills/tui-migrate-setup/scripts/inspect_shared_settings.py:125
for line in contents.splitlines(keepends=True):
is_header, header_path = _table_header_path(line)
if is_header:
current_section = header_path
if current_section in relevant_sections:
selected.append(line)
return "".join(selected)
def _read_toml_object(
path: Path,
paths: list[tuple[str, ...]],
*,
missing_ok: bool,
role: str,
) -> dict[str, Any]:
if path.is_symlink():
raise InspectionError("settings_symlink_rejected")
if missing_ok and not path.exists():
return {}
try:
contents = path.read_text(encoding="utf-8")
selected = _select_relevant_toml(contents, paths)
value = tomllib.loads(selected) if selected else {}
except (OSError, tomllib.TOMLDecodeError) as error:
raise InspectionError(f"{role}_settings_unavailable_or_invalid") from error
if not isinstance(value, dict):
raise InspectionError(f"{role}_settings_unavailable_or_invalid")
return value
def inspect_settings(
schema: dict[str, Any],
source: dict[str, Any],
destination: dict[str, Any],
) -> dict[str, Any]:View on GitHub (pinned to e72fd7aacb)
Solutions
- Replace the symlink with a real file: cp -L link tmp && mv tmp link-path, then re-run
- Point the argument directly at the real file the symlink resolves to
- Reconfigure the dotfiles manager to template/copy this settings file instead of symlinking it
Example fix
# before ~/.warp/settings.toml -> ~/dotfiles/warp/settings.toml (symlink) python inspect_shared_settings.py --source ~/.warp/settings.toml ... # error: settings_symlink_rejected # after cp -L ~/.warp/settings.toml /tmp/settings.toml && mv /tmp/settings.toml ~/.warp/settings.toml python inspect_shared_settings.py --source ~/.warp/settings.toml ...
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
for label, p in (('source', Path(args.source)), ('destination', Path(args.destination))):
if p.is_symlink():
raise SystemExit(f'{label} settings file {p} is a symlink; materialize it first') Try / catch
if result.returncode != 0 and 'settings_symlink_rejected' in result.stderr:
# resolve with readlink -f, or cp -L to materialize, then re-run the inspection
... Prevention
- Configure dotfiles managers to copy/template settings files, not symlink
- Pre-check is_symlink on both settings paths before migration
- Keep the settings file real and store the source of truth in the repo instead
When it happens
Trigger: Settings file managed by a dotfiles manager (stow, chezmoi, an install Makefile) that symlinks the settings TOML into place; a manual ln -s to a shared config across machines.
Common situations: Developers with dotfiles repos; shared configs across machines via symlink; fresh clones where the manager symlinked instead of materializing real files.
Related errors
- config_symlink_rejected
- {role}_settings_unavailable_or_invalid
- source_config_unavailable
- config_unavailable
- config_not_regular_file
AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16).
Data as JSON: /api/errors/4cf35a8977adb7ab.
Report an issue: GitHub.