{"record":{"id":"93f6c57ed57bf31a","repo":"Graphify-Labs/graphify","slug":"gws-is-required-for-google-workspace-export-insta","errorCode":null,"errorMessage":"gws is required for Google Workspace export. Install it from https://github.com/googleworkspace/cli and run `gws auth login -s drive`.","messagePattern":"gws is required for Google Workspace export\\. Install it from https://github\\.com/googleworkspace/cli and run `gws auth login -s drive`\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"graphify/google_workspace.py","lineNumber":97,"sourceCode":"        resource_id = str(data.get(\"resource_id\") or \"\")\n        if \":\" in resource_id:\n            file_id = resource_id.split(\":\", 1)[1]\n\n    if not file_id:\n        raise RuntimeError(f\"Google Workspace shortcut {path} does not include a Drive file ID\")\n\n    return {\n        \"file_id\": str(file_id),\n        \"url\": url or None,\n        \"resource_key\": _extract_resource_key(url, data),\n        \"account\": str(data.get(\"email\")) if data.get(\"email\") else None,\n    }\n\n\ndef _run_gws_export(file_id: str, mime_type: str, output: Path, resource_key: str | None = None) -> None:\n    exe = shutil.which(\"gws\")\n    if not exe:\n        raise RuntimeError(\n            \"gws is required for Google Workspace export. Install it from \"\n            \"https://github.com/googleworkspace/cli and run `gws auth login -s drive`.\"\n        )\n\n    params: dict[str, str] = {\"fileId\": file_id, \"mimeType\": mime_type}\n    # Drive resource keys are sent via X-Goog-Drive-Resource-Keys. The current\n    # gws export command has no custom-header flag, so do not pass resourceKey\n    # as an unsupported query parameter.\n    _ = resource_key\n    output = output.resolve()\n    output.parent.mkdir(parents=True, exist_ok=True)\n    timeout = int(os.environ.get(\"GRAPHIFY_GOOGLE_WORKSPACE_TIMEOUT\", \"120\"))\n    result = subprocess.run(\n        [exe, \"drive\", \"files\", \"export\", \"--params\", json.dumps(params), \"-o\", output.name],\n        capture_output=True,\n        cwd=output.parent,\n        text=True,\n        timeout=timeout,","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/Graphify-Labs/graphify/blob/7fe58b0b0f3873be9a21c30106b8b8527c353aa6/graphify/google_workspace.py#L79-L115","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Install the CLI from https://github.com/googleworkspace/cli and ensure its bin dir is on PATH","Authenticate: `gws auth login -s drive`","Verify resolution with `which gws` in the exact shell/environment that runs graphify (CI and cron often have minimal PATHs)","If you don't need Google docs in the graph, move the shortcuts out of the scanned tree"],"exampleFix":"# before\ngraphify build .   # RuntimeError: gws is required for Google Workspace export\n\n# after (per project README)\n# install the Google Workspace CLI, then:\ngws auth login -s drive\ngraphify build .","handlingStrategy":"validation","validationCode":"import shutil\n\nif shutil.which(\"gws\") is None:\n    raise SystemExit(\n        \"gws CLI not on PATH. Install from https://github.com/googleworkspace/cli \"\n        \"and run `gws auth login -s drive`.\"\n    )","typeGuard":null,"tryCatchPattern":"try:\n    export_google_shortcut(path, out_dir)\nexcept RuntimeError as e:\n    if \"gws is required\" in str(e):\n        raise SystemExit(f\"setup error: {e}\")\n    raise","preventionTips":["Add a `shutil.which('gws')` preflight to any pipeline touching Google shortcuts","In CI/cron, export a PATH that includes the gws install location","Keep .gdoc/.gsheet files out of scanned trees on machines without gws"],"tags":["google-workspace","external-cli","path","dependency","ingest"],"backgroundTag":null,"analyzedSha":"7fe58b0b0f3873be9a21c30106b8b8527c353aa6","analyzedAt":"2026-08-14T19:23:21.323Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}