ruvnet/ruflo · error · Error

GCS upload failed: ${error}

Error message

GCS upload failed: ${error}

What it means

Thrown by uploadToGCS() in the pattern-transfer storage backend when the underlying `gcloud storage cp` subprocess (run via execFileSync) exits non-zero. The catch block unlinks the temp file and re-wraps the cause, so the message is an umbrella over every gcloud CLI failure: missing binary, expired credentials, nonexistent bucket, IAM denial, or network error. It only fires on the `cp` step; a failed metadata update is silently ignored because the upload itself succeeded.

Source

Thrown at v3/@claude-flow/cli/src/transfer/storage/gcs.ts:191

    return {
      success: true,
      uri,
      publicUrl,
      size: content.length,
      checksum,
      contentId,
    };
  } catch (error) {
    // Clean up temp file on error (validate path is within temp dir)
    try {
      const resolvedTemp = path.resolve(tempFile);
      if (resolvedTemp.startsWith(path.resolve(tempDir))) {
        fs.unlinkSync(tempFile);
      }
    } catch { /* ignore */ }

    throw new Error(`GCS upload failed: ${error}`);
  }
}

/**
 * Download content from Google Cloud Storage
 */
export async function downloadFromGCS(
  uri: string,
  config?: GCSConfig
): Promise<Buffer | null> {
  const cfg = config || getGCSConfig();

  console.log(`[GCS] Downloading from ${uri}...`);

  // Write to temp file first
  const tempDir = process.env.TMPDIR || '/tmp';
  const tempFile = path.join(tempDir, `claude-flow-download-${Date.now()}.json`);

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Run `gcloud --version` on the machine doing the upload; if it fails, install the Google Cloud CLI and reopen the shell so it is on PATH.
  2. Authenticate and select a project: `gcloud auth login && gcloud config set project YOUR_PROJECT` (or set the project via the config used by uploadToGCS).
  3. Verify bucket access: `gcloud storage ls gs://YOUR-BUCKET` — fix the GCS_BUCKET value or grant the identity roles/storage.objectCreator on the bucket.
  4. Re-run the publish/transfer operation; if the failure is intermittent, wrap uploadToGCS in a retry with backoff.

Example fix

// before
GCS_BUCKET=typo-bucket npx claude-flow hooks transfer publish
// → Error: GCS upload failed: Error: Command failed: gcloud storage cp ...

// after (terminal)
gcloud auth login
gcloud config set project my-project
gcloud storage ls gs://my-patterns-bucket   # proves credentials + bucket
GCS_BUCKET=my-patterns-bucket npx claude-flow hooks transfer publish
Defensive patterns

Strategy: retry

Validate before calling

import { execFileSync } from 'node:child_process';
import { isGCloudAuthenticated } from './gcs.js';

function gcloudAvailable(): boolean {
  try { execFileSync('gcloud', ['--version'], { stdio: 'pipe' }); return true; }
  catch { return false; }
}
// call before uploading:
if (!gcloudAvailable()) throw new Error('install the gcloud CLI first');
if (!(await isGCloudAuthenticated())) throw new Error('run: gcloud auth login');

Try / catch

try {
  const result = await uploadToGCS(content, { name, config });
} catch (err) {
  const msg = err instanceof Error ? err.message : String(err);
  if (!msg.startsWith('GCS upload failed:')) throw err;      // not our error
  if (/ENOENT/.test(msg)) throw new Error('gcloud CLI not installed');
  if (/No project|quota|Unauthorized|401|403/.test(msg)) throw new Error(`auth/bucket perms: ${msg}`);
  await backoffRetry(() => uploadToGCS(content, { name, config }), 3); // transient network
}

Prevention

When it happens

Trigger: Calling uploadToGCS() (directly or via the publish/`hooks transfer` flow with the GCS backend) when: (1) the gcloud CLI is not installed (spawn ENOENT); (2) `gcloud auth login` was never run or the token expired; (3) GCS_BUCKET names a bucket that does not exist or the account lacks object-create permission; (4) config.projectId points at the wrong GCP project; (5) a transient network outage interrupts `gcloud storage cp`. Note: GCS_BUCKET being unset fails earlier with a distinct 'GCS not configured' error, so this message implies configuration was present but the upload operation itself failed.

Common situations: CI containers that never preinstalled the Cloud SDK; GCS_BUCKET exported on a laptop whose `gcloud config set project` was never set, so gcloud errors with 'No project found'; read-only service accounts; typo'd bucket names; corporate proxies blocking storage.googleapis.com.

Related errors


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/8e78cd51946b4f41. Report an issue: GitHub.