{"record":{"id":"d2b24ae41fe36f60","repo":"github/copilot-sdk","slug":"could-not-determine-directory-for-clipath","errorCode":null,"errorMessage":"Could not determine directory for '{cliPath}'.","messagePattern":"Could not determine directory for '(.+?)'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"dotnet/src/Client.cs","lineNumber":2557,"sourceCode":"        }\n        else if (OperatingSystem.IsMacOS()) os = \"osx\";\n        else return null;\n\n        var arch = System.Runtime.InteropServices.RuntimeInformation.OSArchitecture switch\n        {\n            System.Runtime.InteropServices.Architecture.X64 => \"x64\",\n            System.Runtime.InteropServices.Architecture.Arm64 => \"arm64\",\n            _ => null,\n        };\n\n        return arch != null ? $\"{os}-{arch}\" : null;\n    }\n\n    private static string ResolveRuntimePathForExplicitCli(string cliPath)\n    {\n        var fullEntrypoint = Path.GetFullPath(cliPath);\n        var directory = Path.GetDirectoryName(fullEntrypoint)\n            ?? throw new InvalidOperationException($\"Could not determine directory for '{cliPath}'.\");\n        var flatLibraryPath = Path.GetFullPath(\n            $\"{directory}{Path.DirectorySeparatorChar}{FfiRuntimeHost.GetRuntimeLibraryFileName()}\");\n        if (File.Exists(flatLibraryPath))\n        {\n            return flatLibraryPath;\n        }\n        var adjacentPrebuildPath = Path.Combine(directory, \"runtime.node\");\n        if (File.Exists(adjacentPrebuildPath))\n        {\n            return adjacentPrebuildPath;\n        }\n        var prebuildsLibraryPath = Path.Combine(\n            directory, \"prebuilds\", GetNapiPrebuildsFolderOrThrow(), \"runtime.node\");\n        return File.Exists(prebuildsLibraryPath)\n            ? prebuildsLibraryPath\n            : throw new InvalidOperationException(\n                $\"FFI runtime library not found. Looked for '{flatLibraryPath}', '{adjacentPrebuildPath}', and '{prebuildsLibraryPath}'.\");\n    }","sourceCodeStart":2539,"sourceCodeEnd":2575,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/dotnet/src/Client.cs#L2539-L2575","documentation":"ResolveRuntimePathForExplicitCli computes the directory of an explicitly configured CLI entrypoint path to search for the runtime library next to it. Path.GetDirectoryName returned null after Path.GetFullPath (e.g. a path rooted to a filesystem root with no directory component), so the client cannot proceed and throws.","triggerScenarios":"Path.GetDirectoryName(Path.GetFullPath(cliPath)) returns null at Client.cs:2557 when the explicit CLI path resolves to a bare root (e.g. \"/\" or \"C:\\\") or another form with no directory portion.","commonSituations":"Setting the CLI path option to a root path, an empty-ish path that normalizes to a root, or a malformed path; passing an environment variable or argument that was meant to name the CLI directory rather than a file; misconfigured container/image where the expected CLI file is missing and a fallback root path is used.","solutions":["Set the explicit CLI path to a full path of the actual CLI file (not a root or directory), e.g. /usr/local/bin/copilot.","Guard the configured value before assigning it: check File.Exists and that it has a parent directory.","If the value comes from an env var or CLI flag, validate/trim it and fail fast with a clear message when it is not a file path.","Alternatively place the runtime library in the CLI's directory (flat layout) so resolution succeeds once the path is correct."],"exampleFix":"// before\noptions.CliPath = Environment.GetEnvironmentVariable(\"COPILOT_CLI\") ?? \"/\";\n\n// after\nvar cli = Environment.GetEnvironmentVariable(\"COPILOT_CLI\");\noptions.CliPath = cli is { Length: > 0 } && File.Exists(cli)\n    ? Path.GetFullPath(cli)\n    : throw new InvalidOperationException($\"COPILOT_CLI must be a valid CLI file path, got '{cli}'\");","handlingStrategy":"validation","validationCode":"if (string.IsNullOrWhiteSpace(cliPath) ||\n    !File.Exists(cliPath) ||\n    Path.GetDirectoryName(Path.GetFullPath(cliPath)) is null)\n    throw new ArgumentException($\"CliPath must be a valid file path, got '{cliPath}'\");","typeGuard":"static bool IsValidCliPath(string? p) =>\n    p is { Length: > 0 } && File.Exists(p) &&\n    Path.GetDirectoryName(Path.GetFullPath(p)) is { Length: > 0 };","tryCatchPattern":"try\n{\n    await client.StartAsync();\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Could not determine directory\"))\n{\n    logger.LogError(ex, \"Configured CliPath has no resolvable directory\");\n}","preventionTips":["Point CliPath at the actual CLI executable file, never a root or directory.","Validate env vars/flags feeding CliPath before constructing options.","Resolve default paths from known install locations rather than falling back to '/'"],"tags":["path","invalid-path","runtime"],"backgroundTag":"invalid-argument-value","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}