{"record":{"id":"55e05e0fb16ec917","repo":"warpdotdev/warp","slug":"source-config-unavailable","errorCode":"source_config_unavailable","errorMessage":"source_config_unavailable","messagePattern":"source_config_unavailable","errorType":"exception","errorClass":"MergeError","httpStatus":null,"severity":"error","filePath":"resources/bundled/skills/tui-migrate-setup/scripts/merge_mcp_config.py","lineNumber":109,"sourceCode":"        child = current.get(segment)\n        if not isinstance(child, dict):\n            child = {}\n            current[segment] = child\n        current = child\n    if path:\n        current[path[-1]] = value\n    else:\n        document.clear()\n        document.update(value)\n\n\ndef _read_regular_file(path: Path, *, missing_ok: bool) -> tuple[bytes, int | None]:\n    try:\n        metadata = path.lstat()\n    except FileNotFoundError:\n        if missing_ok:\n            return b\"\", None\n        raise MergeError(\"source_config_unavailable\")\n    except OSError as error:\n        raise MergeError(\"config_unavailable\") from error\n\n    if stat.S_ISLNK(metadata.st_mode):\n        raise MergeError(\"config_symlink_rejected\")\n    if not stat.S_ISREG(metadata.st_mode):\n        raise MergeError(\"config_not_regular_file\")\n    if metadata.st_size > MAX_CONFIG_BYTES:\n        raise MergeError(\"config_too_large\")\n\n    flags = os.O_RDONLY\n    if hasattr(os, \"O_NOFOLLOW\"):\n        flags |= os.O_NOFOLLOW\n    try:\n        descriptor = os.open(path, flags)\n        with os.fdopen(descriptor, \"rb\") as file:\n            raw = file.read(MAX_CONFIG_BYTES + 1)\n    except OSError as error:","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/warpdotdev/warp/blob/e72fd7aacbbb2236d9b3be2aad7e7178fe94b4bc/resources/bundled/skills/tui-migrate-setup/scripts/merge_mcp_config.py#L91-L127","documentation":"Raised by _read_regular_file() when lstat() on the config path raises FileNotFoundError and the caller passed missing_ok=False — the file is required and absent. (In the current merge_mcp_config.py, load_config() passes missing_ok=True, so an absent file is tolerated as an empty config; this code enforces the required-source contract for stricter callers of the helper.)","triggerScenarios":"lstat reports ENOENT while missing_ok=False: the --source path does not exist (or its parent directory is gone), e.g. pointing at a Warp MCP config location that was never created on this machine.","commonSituations":"First run on a machine where the GUI MCP config was never written; wrong path passed via --source; home-directory resolution differences (launchd/systemd/root vs interactive user).","solutions":["Check the path component by component (ls the parent directory) and correct the --source argument","If the source legitimately does not exist there is nothing to merge — create it via the owning app or point at the real config location","Verify $HOME / user context resolves to the expected home when the path is built from ~"],"exampleFix":"# before\npython merge_mcp_config.py --source ~/.claude/mcp.json --destination ... # file never existed\n# error: source_config_unavailable\n\n# after\npython merge_mcp_config.py --source ~/.claude.json --destination ... # actual config location","handlingStrategy":"validation","validationCode":"import os\n\nif not os.path.exists(source_path):\n    raise SystemExit(f'source config missing: {source_path}')","typeGuard":null,"tryCatchPattern":"if result.returncode != 0 and 'source_config_unavailable' in result.stderr:\n    # the required source file is absent — fix the --source path and retry\n    ...","preventionTips":["Verify the source config path exists before invoking","Resolve ~ explicitly against the intended home directory","Distinguish 'not created yet' from 'wrong path' before migrating"],"tags":["filesystem","config","io"],"backgroundTag":null,"analyzedSha":"e72fd7aacbbb2236d9b3be2aad7e7178fe94b4bc","analyzedAt":"2026-08-16T08:27:25.381Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}