6

I'm following thist tutorial : https://cloud.google.com/tasks/docs/tutorial-gcf

To create a Task that would call a cloud function.

I've done quite some tries and still get this error:

enter image description here

If I change the body encoding to something else, I get another error about serialisation method.

It's likely not a permission issues, as I got some before and got rid of it.

The object which is pass to the createTask() is the following :

task: {
  httpRequest: {
    url: "https://europe-west1-project_id.cloudfunctions.net/FunctionName"
    httpMethod: "POST"
    oidcToken: {
      serviceAccountEmail: "cf-targetFunctionSA@project_id.gserviceaccount.com"
    }
  body: ""
  headers: {
    Content-Type: "application/json"
  }
}

(or with body: base64 encoded json string.)

The code I use is the following :

'use strict';
const common            = require('./common');
const {v2beta3}         = require('@google-cloud/tasks');
const cloudTasksClient  = new v2beta3.CloudTasksClient();

let projectName = common.getProjectName();
let location    = "europe-west3";
let queue       = "compute-stats-on-mysql";
const parent    = cloudTasksClient.queuePath(projectName, location, queue);

async function createTask(url, serviceAccount, data)
{
  const dataBuffer  = Buffer.from(JSON.stringify(data)).toString('base64');
  const task = {
    httpRequest: {
      httpMethod: 'POST',
      url:url,
      oidcToken: {
        serviceAccountEmail: serviceAccount,
      },
      headers: {
        'Content-Type': 'application/json',
      },
      body:dataBuffer,
    },
  };


  try
  {
    // Send create task request.
    common.logDebug(`Before creating task`, {parent:parent,task:task, data:data});
    const [response] = await cloudTasksClient.createTask({parent, task});
    common.logDebug(`Created task ${response.name}`, {parent:parent,task:task, response:response, data:data});
    return response;
  }
  catch (error)
  {
    // Construct error for Stackdriver Error Reporting
    console.error("error while creating tasks",error);
  }
}

module.exports = {
  createTask : createTask,
  cloudTasksClient:cloudTasksClient
};

The lack of details in the error makes me hit a wall blind...

Any suggestions ?

4 Answers 4

4

My service account was missing a part...

it was

"cf-"+functionName+"@"+projectName+".gserviceaccount.com";

instead of

"cf-"+functionName+"@"+projectName+".iam.gserviceaccount.com";

I left out the ".iam" during my numerous test to make it work.

For sure there's room for improvement in the error messages.

Sign up to request clarification or add additional context in comments.

Comments

3

I had same problem. In your case I think there is not property scheduleTime into task param. To me, the scheduleTime.seconds was with a wrong value.

2 Comments

I was using Date.now() instead of Date.now() / 1000
I misinterpreted the scheduleTime thinking it was "from now" rather than "a full timestamp represented in seconds of a date you want it to be at" So if you want it to be 15 minutes from now, the property would be: seconds: (Date.now() / 1000) + (15 * 60)
1

We too faced "status": "INVALID_ARGUMENT" error while triggering the Cloud Workflow via Cloud Tasks at a scheduled date time. Could have been better if they could have provided more information than just this vague INVALID_ARGUMENT as status on task run.

Error:

attemptResponseLog: {
attemptDuration: "0.026078s"
dispatchCount: "1"
maxAttempts: 0
responseCount: "1"
retryTime: "2023-06-16T12:29:59.466801Z"
scheduleTime: "2023-06-23T12:24:28.851Z"
status: "INVALID_ARGUMENT"
targetAddress: "POST https://workflowexecutions.googleapis.com/v1/projects/***/locations/us-central1/workflows/workflow-***/executions"
targetType: "HTTP"
}

For us, issue was found with the body payload that was added to httpRequest to Cloud task. Make sure:

  1. body of httpRequest object is doubly escaped e.g.

{"argument": "{\"foo\": \"bar\"}"}

  1. body has to be base64encoded string if added via REST APIs programatically e.g.

String payload=String.format("{"argument": "%s"}", payload.replace(""", "\"")); String base64EncodedPayload = com.google.api.client.util.Base64.encodeBase64URLSafeString(payload.getBytes());//Request Body, A base64-encoded string.

httpTargetJSON.put("url",workflowExecutionURL); httpTargetJSON.put("httpMethod","POST");
httpTargetJSON.put("body",base64EncodedPayload);

Equivalent gcloud command would be something as follows (you can quickly run this over cloud console shell/terminal):

gcloud tasks create-http-task --queue="WorkflowTestQueue" --url="https://workflowexecutions.googleapis.com/v1/projects/{YourProjectID}/locations/{yourProjectLocation}/workflows/{targetWorkflowID}/executions" --body-content="{"argument": "{\"foo\": \"bar\"}"}" --oauth-service-account-email="YOUR_SERVICE_ACCOUNT.gserviceaccount.com"

Comments

1

In my case, the error was that I provided the service account email in the format serviceAccount:[email protected]. The correct format is just [email protected].

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.