Graphify-Labs/graphify · error · RuntimeError

gws is required for Google Workspace export. Install it from

Error message

gws is required for Google Workspace export. Install it from https://github.com/googleworkspace/cli and run `gws auth login -s drive`.

What it means

Raised by _run_gws_export when the external `gws` CLI (Google Workspace CLI) is not on PATH. graphify does not implement Drive downloads itself; it shells out to `gws drive files export`. shutil.which('gws') returning None means the binary is absent (or not executable/on PATH), and the error bundles both the install URL and the required auth login step.

Source

Thrown at graphify/google_workspace.py:97

        resource_id = str(data.get("resource_id") or "")
        if ":" in resource_id:
            file_id = resource_id.split(":", 1)[1]

    if not file_id:
        raise RuntimeError(f"Google Workspace shortcut {path} does not include a Drive file ID")

    return {
        "file_id": str(file_id),
        "url": url or None,
        "resource_key": _extract_resource_key(url, data),
        "account": str(data.get("email")) if data.get("email") else None,
    }


def _run_gws_export(file_id: str, mime_type: str, output: Path, resource_key: str | None = None) -> None:
    exe = shutil.which("gws")
    if not exe:
        raise RuntimeError(
            "gws is required for Google Workspace export. Install it from "
            "https://github.com/googleworkspace/cli and run `gws auth login -s drive`."
        )

    params: dict[str, str] = {"fileId": file_id, "mimeType": mime_type}
    # Drive resource keys are sent via X-Goog-Drive-Resource-Keys. The current
    # gws export command has no custom-header flag, so do not pass resourceKey
    # as an unsupported query parameter.
    _ = resource_key
    output = output.resolve()
    output.parent.mkdir(parents=True, exist_ok=True)
    timeout = int(os.environ.get("GRAPHIFY_GOOGLE_WORKSPACE_TIMEOUT", "120"))
    result = subprocess.run(
        [exe, "drive", "files", "export", "--params", json.dumps(params), "-o", output.name],
        capture_output=True,
        cwd=output.parent,
        text=True,
        timeout=timeout,

View on GitHub (pinned to 7fe58b0b0f)

Solutions

  1. Install the CLI from https://github.com/googleworkspace/cli and ensure its bin dir is on PATH
  2. Authenticate: `gws auth login -s drive`
  3. Verify resolution with `which gws` in the exact shell/environment that runs graphify (CI and cron often have minimal PATHs)
  4. If you don't need Google docs in the graph, move the shortcuts out of the scanned tree

Example fix

# before
graphify build .   # RuntimeError: gws is required for Google Workspace export

# after (per project README)
# install the Google Workspace CLI, then:
gws auth login -s drive
graphify build .
Defensive patterns

Strategy: validation

Validate before calling

import shutil

if shutil.which("gws") is None:
    raise SystemExit(
        "gws CLI not on PATH. Install from https://github.com/googleworkspace/cli "
        "and run `gws auth login -s drive`."
    )

Try / catch

try:
    export_google_shortcut(path, out_dir)
except RuntimeError as e:
    if "gws is required" in str(e):
        raise SystemExit(f"setup error: {e}")
    raise

Prevention

When it happens

Trigger: Ingesting a .gdoc/.gsheet/.gslides shortcut in an environment where `gws` was never installed, is installed but not on PATH (npm global bin missing from PATH, renamed binary), or lacks execute permission.

Common situations: Fresh machines/containers where graphify was installed but the separate Google Workspace CLI wasn't; nvm/npm global bin directory not on PATH in non-interactive shells (cron, CI); gws installed under a different user.

Related errors


AI-assisted analysis of Graphify-Labs/graphify@7fe58b0b0f (2026-08-14). Data as JSON: /api/errors/93f6c57ed57bf31a. Report an issue: GitHub.