ToolJet/ToolJet · error · QueryError

Query could not be completed

Error message

Query could not be completed

What it means

The GCS plugin wraps its operation switch (list_buckets, list_files, get_file, upload_file, signed_url_for_get, signed_url_for_put) in a try/catch that re-throws any failure as QueryError 'Query could not be completed' with error.message as description. Notably there is NO default case, so an unknown operation silently returns an empty result ({}) rather than erroring — only genuine @google-cloud/storage failures are caught here.

Source

Thrown at plugins/packages/gcs/lib/index.ts:34

          break;
        case 'list_files':
          result = await listFiles(client, queryOptions);
          break;
        case 'get_file':
          result = await getFile(client, queryOptions);
          break;
        case 'upload_file':
          result = await uploadFile(client, queryOptions);
          break;
        case 'signed_url_for_get':
          result = await signedUrlForGet(client, queryOptions);
          break;
        case 'signed_url_for_put':
          result = await signedUrlForPut(client, queryOptions);
          break;
      }
    } catch (error) {
      throw new QueryError('Query could not be completed', error.message, {});
    }

    return {
      status: 'ok',
      data: result,
    };
  }

  async testConnection(sourceOptions: SourceOptions): Promise<ConnectionTestResult> {
    const client: Storage = await this.getConnection(sourceOptions);
    await listBuckets(client, {});

    return {
      status: 'ok',
    };
  }

  async getConnection(sourceOptions: SourceOptions): Promise<any> {

View on GitHub (pinned to 20602a8e10)

Solutions

  1. Read the QueryError.description — it carries the @google-cloud/storage message (e.g. 'The specified bucket does not exist').
  2. Confirm the private_key JSON is complete and the service account has the required Storage IAM role (roles/storage.objectViewer / objectAdmin / admin as needed).
  3. Verify the bucket name and that it belongs to the key's project (or is shared with the principal).
  4. For signed URLs, ensure the private_key has correct newline escaping.

Example fix

// before — bucket name typo
queryOptions = { operation: 'list_files', bucket: 'mybucket' };
// after
queryOptions = { operation: 'list_files', bucket: 'my-bucket' };
Defensive patterns

Strategy: validation

Validate before calling

function validateGcsQuery(qo) {
  const OPS = ['list_buckets','list_files','get_file','upload_file','signed_url_for_get','signed_url_for_put'];
  if (!OPS.includes(qo.operation)) { /* note: unknown op returns empty {}, not an error */ return; }
  if (['list_files','get_file','upload_file'].includes(qo.operation) && !qo.bucket) throw new Error('bucket required');
}

Type guard

function isGcsOperation(op: unknown): op is 'list_buckets'|'list_files'|'get_file'|'upload_file'|'signed_url_for_get'|'signed_url_for_put' {
  return typeof op === 'string' && ['list_buckets','list_files','get_file','upload_file','signed_url_for_get','signed_url_for_put'].includes(op);
}

Try / catch

try { await plugin.run(sourceOptions, queryOptions); }
catch (e) { if (e instanceof QueryError && e.message === 'Query could not be completed') { console.error('GCS detail:', e.description); } else throw e; }

Prevention

When it happens

Trigger: list_buckets fails because the service account lacks storage.buckets.list. list_files/get_file against a non-existent bucket or object. upload_file with an invalid destination path or insufficient storage.objects.create permission. signed_url_for_get/put when the private_key is malformed so signing fails. Network error reaching the GCS JSON API.

Common situations: Service account JSON missing or with a corrupted private_key (\n not unescaped). Project ID mismatch between the key and where buckets live. Bucket in a different region/project not granted to the principal. HMAC or OAuth scope too narrow for signed URL generation. Large upload_file payload exceeding limits.

Related errors


AI-assisted analysis of ToolJet/ToolJet@20602a8e10 (2026-08-13). Data as JSON: /api/errors/55250108bc47c76c. Report an issue: GitHub.