ruvnet/ruflo · error · Error
Invalid GCS object path: ${objectPath}
Error message
Invalid GCS object path: ${objectPath} What it means
After the filename check, uploadToGCS composes objectPath = config.prefix ? `${prefix}/${fileName}` : fileName and validates the whole path through isValidObjectPath() — the second half of the S-1 command-injection guard, since the path becomes a gcloud argument. A prefix containing spaces, shell metacharacters, absolute-path markers, or traversal sequences makes the combined path fail even when the filename itself is clean.
Source
Thrown at v3/@claude-flow/cli/src/transfer/storage/gcs.ts:133
}
const contentId = generateContentId(content);
const checksum = crypto.createHash('sha256').update(content).digest('hex');
const fileName = options.name || `${contentId}.cfp.json`;
// Validate filename to prevent path traversal
if (!/^[a-zA-Z0-9._\-]+$/.test(fileName) || fileName.includes('..')) {
throw new Error(`Invalid filename: ${fileName}`);
}
const objectPath = config.prefix ? `${config.prefix}/${fileName}` : fileName;
// S-1: Validate bucket name and object path to prevent command injection
if (!isValidBucketName(config.bucket)) {
throw new Error(`Invalid GCS bucket name: ${config.bucket}`);
}
if (!isValidObjectPath(objectPath)) {
throw new Error(`Invalid GCS object path: ${objectPath}`);
}
console.log(`[GCS] Uploading to gs://${config.bucket}/${objectPath}...`);
// Write content to temp file
const tempDir = process.env.TMPDIR || '/tmp';
const tempFile = path.join(tempDir, `claude-flow-upload-${Date.now()}.json`);
fs.writeFileSync(tempFile, content);
try {
// Build gcloud args (array form prevents shell injection)
const uploadArgs = ['storage', 'cp', tempFile, `gs://${config.bucket}/${objectPath}`];
if (config.projectId) uploadArgs.push(`--project=${config.projectId}`);
uploadArgs.push(`--content-type=${options.contentType || 'application/json'}`);
execFileSync('gcloud', uploadArgs, { encoding: 'utf-8', stdio: 'pipe' });
// Set metadata if providedView on GitHub (pinned to fa13ee4ad6)
Solutions
- Keep prefix segments simple: lowercase/digits/hyphens/underscores, no leading slash, no spaces or shell metacharacters — e.g. 'patterns/2024'
- Sanitize user-supplied prefixes before passing GCSConfig (strip leading '/', collapse '//', reject metacharacters)
- Drop the prefix entirely (flat layout) if you do not need folder structure
- Treat any metacharacter in this value as hostile input — the guard exists because the path reaches a shell-launched gcloud command
Example fix
// before
await uploadToGCS(content, { config: { bucket: 'my-bucket', prefix: 'my patterns/2024' } });
// space in prefix -> Invalid GCS object path: my patterns/2024/pattern.json
// after
await uploadToGCS(content, { config: { bucket: 'my-bucket', prefix: 'patterns/2024' } }); Defensive patterns
Strategy: validation
Validate before calling
function sanitizeGcsPrefix(prefix: string): string {
const cleaned = prefix.replace(/\/+/g, '/').replace(/^\/+/, '').replace(/\/+$/, '');
if (!/^[a-zA-Z0-9._\/-]*$/.test(cleaned) || cleaned.includes('..')) {
throw new Error(`Unsafe GCS prefix: ${JSON.stringify(prefix)}`);
}
return cleaned;
}
await uploadToGCS(content, {
config: { bucket, prefix: sanitizeGcsPrefix(userPrefix) },
}); Type guard
function isValidGcsObjectPath(objectPath: string): boolean {
return /^[a-zA-Z0-9._\/-]+$/.test(objectPath)
&& !objectPath.includes('..')
&& !objectPath.startsWith('/')
&& !/[;&|$`"'\s]/.test(objectPath);
} Prevention
- Restrict prefixes to plain path segments: alphanumerics, hyphens, underscores, single slashes — no spaces or shell metacharacters
- Treat prefix and name as untrusted input; sanitize both before building GCSConfig
- Remember why the guard exists: the object path is interpolated into a gcloud CLI argument, so metacharacters are an injection vector, not just a formatting nuisance
When it happens
Trigger: GCSConfig.prefix values like 'my patterns/', '/abs/path', 'a;rm -rf', '../escape', or prefixes with quotes/backticks; a clean fileName combined with a prefix containing spaces or unicode; empty-but-whitespace prefixes.
Common situations: User-defined prefixes from config files or CLI flags; prefixes mirroring local directory trees with spaces; injection attempts on shared systems; trailing slashes doubling up ('prefix//' plus filename).
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- Invalid filename: ${fileName}
- basePath contains disallowed characters
- memory path contains disallowed characters
- Invalid command: contains shell metacharacters
- Invalid command: contains shell metacharacters
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/d5169be407389b3f.
Report an issue: GitHub.