warpdotdev/warp · error · MergeError
config_unavailable
config_unavailable
Error message
config_unavailable
What it means
config_unavailable from the lstat except-OSError branch: the metadata call failed with something other than FileNotFoundError — classically EACCES (search-permission denied on a parent directory), ELOOP (a loop of symlinks; a plain symlink is caught earlier by the S_ISLNK check, so ELOOP here means link cycles), or another filesystem error. The message is deliberately sanitized with no path or errno detail.
Source
Thrown at resources/bundled/skills/tui-migrate-setup/scripts/merge_mcp_config.py:111
child = {}
current[segment] = child
current = child
if path:
current[path[-1]] = value
else:
document.clear()
document.update(value)
def _read_regular_file(path: Path, *, missing_ok: bool) -> tuple[bytes, int | None]:
try:
metadata = path.lstat()
except FileNotFoundError:
if missing_ok:
return b"", None
raise MergeError("source_config_unavailable")
except OSError as error:
raise MergeError("config_unavailable") from error
if stat.S_ISLNK(metadata.st_mode):
raise MergeError("config_symlink_rejected")
if not stat.S_ISREG(metadata.st_mode):
raise MergeError("config_not_regular_file")
if metadata.st_size > MAX_CONFIG_BYTES:
raise MergeError("config_too_large")
flags = os.O_RDONLY
if hasattr(os, "O_NOFOLLOW"):
flags |= os.O_NOFOLLOW
try:
descriptor = os.open(path, flags)
with os.fdopen(descriptor, "rb") as file:
raw = file.read(MAX_CONFIG_BYTES + 1)
except OSError as error:
raise MergeError("config_unavailable") from error
if len(raw) > MAX_CONFIG_BYTES:View on GitHub (pinned to e72fd7aacb)
Solutions
- Walk the path with namei -l <path> (or ls -ld each parent) to find the first inaccessible component and relax permissions there
- Run the merge as the user who owns the config tree
- Resolve symlink cycles (readlink -f) and materialize a real file at the config path
Example fix
# before chmod 700 /home/user/.config # owned by another user; merge runs as service account python merge_mcp_config.py ... # error: config_unavailable # after chmod o+x /home/user/.config # or run the merge as the owning user python merge_mcp_config.py ...
Defensive patterns
Strategy: try-catch
Validate before calling
import os os.stat(source_path) # surfaces EACCES/ELOOP on the path or its parents before the merge runs
Try / catch
if result.returncode != 0 and 'config_unavailable' in result.stderr:
# walk parents with namei -l <path>; fix the first component that denies access, then retry
... Prevention
- Ensure every parent directory of the config is searchable (x bit) by the running user
- Avoid symlink cycles in config paths
- Run the migration as the user who owns the config tree
When it happens
Trigger: A parent directory of the config is not searchable by the current user (mode without x); symlink cycles (a -> b -> a); exotic filesystems returning errors from stat.
Common situations: Configs under permission-hardened directories; containers/sandboxes denying stat; user mismatch between the launching environment and the file owner.
Related errors
- source_config_unavailable
- config_not_regular_file
- config_too_large
- settings_symlink_rejected
- config_symlink_rejected
AI-assisted analysis of warpdotdev/warp@e72fd7aacb (2026-08-16).
Data as JSON: /api/errors/3889544821b931bf.
Report an issue: GitHub.