API PUT call for Updating a Project giving Custom Field with ID {gid of custom field} is not on given object it's definitely on.

Hello. I’m trying to mass update fields on projects from salesforce via workato. All was going fine after some tinkering. I instatiate a project from a template, make an API call to add the custom fields needed from the library. All good. Then I try and push values and nothing works at all.

This is the JSON body for the PUT call:

{
  "data": {
    "custom_fields": {
      "1206042909386231": "ADP",
      "1206014126293873": "This is a test"
     
    }
  }
}

and it will throw this error:

{
    "errors": [
        {
            "message": "Custom field with ID 1206042909386231 is not on given object",
            "help": "For more information on API status codes and how to handle them, read the docs on errors: https://developers.asana.com/docs/errors"
        }
    ]
}

But that field is definitely on the project:

 {
                "gid": "1206043168517206",
                "custom_field": {
                    "gid": "1206014126293873",
                    "name": "BGC System",
                    "resource_subtype": "text",
                    "resource_type": "custom_field",
                    "type": "text",
                    "is_formula_field": false
                },

(this snippet is from the 2nd ID in my little test sample, when I was troubleshooting by getting rid of the first, which is an enum, so I was trying to rule that out by going with just a plain text option, but this is true of literally field I’ve used. They all appear in the returned JSON from polling the project itself by the ID used in the update command above.

I tried using the gid of the container? of the custom field as shown in the last snippet. That didn’t help, and I’m pretty sure I have the right ID considering it’s the list I use to add them to the project to begin with.

So I’m stumped. What do I need to feed this API endpoint so it’s happy?

Hi @Ric_Orna,

Custom fields operate at two levels: you can have a custom field at the task level in which case you add it to a project; you can also have a custom field at a project level in which case it shows up most commonly on a portfolio (though you can see it on the project as well).

At which one of these levels are you trying to operate? Are you wanting to mass update a custom field on tasks in a project; or on projects in a portfolio?

Also, can you share screenshots of the calls you’re making so we can see what API endpoints (or I guess what Workato actions) you’re calling?

I was not aware of a distinction aside from in the library vs added to a project for a custom field. Each project that is instantiated in my workato flow corresponds to a child custom object of Account in Salesforce 1:1. The value in SFDC should push to the new project in Asana.

I think I might need a better understanding of “projects in a portfolio” to actually answer that question definitively. (I’ll go read, but I want to get this response fired back ASAP).

Behold a project, instantiated from a template, then with 38 custom fields added from the library (that works), but no values (The ATS does here on the first line because I just did it there in the UI):

There only needs to be one value per project. I’ll look, but I’m operating on the assumption we might need to go this task level route and isolate it to a dedicated “task” called SFDC fields or something?

I suppose we make a new task called “SFDC Sync Fields”, add it at the top (I have a question about how the insert before/after works), and then populate the values into that specific task?

Let me know if there is a more appropriate way?
If not, Can you help with the syntax of that inserting at the top of a project?

Also confirmation about how the structure of a request should be. I recall seeing a relevant forum post, so I’ll go back and start there, but an example of each data type would be awesome if you have it.

I suppose your request for screenshots of postman/workato isn’t really relevant if I have to do this to a task. it does raise the question what the hell does this endpoint do with custom field updates? I got stuck on it, because I assumed that was the method.

Yeah, that’s what I was afraid of; you’re confusing the two levels of custom fields I described (but don’t feel bad, it’s a common thing and the documentation is not clear).

Before I answer more fully, the key question is what Asana subscription level are you on? Is it Premium/Starter or something higher (i.e. Business/Advanced/Enterprise)? The reason that’s key is portfolios are not available on Premium/Starter.

We have portfolios. Not sure which level, but at least business.

OK, good!

So I would say you have two choices. The first is to set the custom fields at the portfolio level so that they exist on projects in that portfolio. That’s the correct fit for your data because you say

There only needs to be one value per project.

The only potential “downside” to that approach is that if you’re not really using portfolios, and it seems like you’re not, then the only other place where these project custom fields display is when you select “Edit project details” from the project dropdown menu:



If you’re OK with that as the place your users will go to see those custom field values, then this is the best approach since, as I say, it matches your data model. Or you can start using portfolios and see the project custom fields there:

The second option is the one you mentioned; create a “fake task” that will hold the values. This is a kludge for multiple reasons; first, it doesn’t fit your data model; second, users can muck with this “fake task” (they might move it elsewhere in the project, mark it complete, delete it altogether, etc.); third, the custom fields, while you fill them in for just this fake task, will be sitting on ALL tasks in the project and people can set them on any task, which is not what you will want.

To take the first approach, you’ll set the custom fields for a portfolio using this endpoint, and you’ll set/update the actual values for the custom fields using the “Update a project” endpoint that you’ve been trying to use.

To take the second approach, you’ll set the custom fields for a project using this endpoint that you used previously, and you’ll set the actual values for the “fake task” using this endpoint.

Clear as mud??

2 Likes

Ok, I went with option A, and got the results for normal text fields working fine. Everything else doesn’t work, and the documentation says absolutely nothing about how other types of data should be formatted. The one thing the documentation does mention, Dates, I gave it in the manner it says in the documentation and it still errors out. The errors are next to useless. It’s not a JSON object there’s no published specification for? Gee Thanks.

400 Bad Request: {"errors":[{"message":"date_value: DayAndDateTime is not a JSON object: 2022-05-23","help":"For more information on API status codes and how to handle them, read the docs on errors: https://developers.asana.com/docs/errors"},{"message":"date_value: DayAndDateTime is not a JSON object: 2021-09-01","help":"For more information on API status codes and how to handle them, read the docs on errors: https://developers.asana.com/docs/errors"},{"message":"date_value: DayAndDateTime is not a JSON object: 2022-10-25","help":"For more information on API status codes and how to handle them, read the docs on errors: https://developers.asana.com/docs/errors"},{"message":"date_value: DayAndDateTime is not a JSON object: 2022-07-22"

I am supposed to do it like the task thing? Where are the examples for each data type?

Well, I have Date figured after skimming forum posts…

{
  "data": {
    "custom_fields": 
    "1206014126293873": "This is a Text Field",
    "1206014780394095": {"date": "2022-08-18"}
     
    }
  }
}

I still need enum, multi_enum, number, and people to actually have the info I need to craft this set of API calls.

Why is this not in the documentation? I’ve found people complaining about this from 2021 in the forums here. This is a lot of wasted time.

Hi @Ric_Orna,

I agree it’s not spelled out as clear as it could be in the API docs but most of the info is there. See for example Custom fields

For enum and number, just follow the syntax shown there (for enum, but sure to supply the enum option’s gid, not the text name of the option).

For multi-enum and people, it’s an array since you can have multiple values: Add custom field value - #2 by Phil_Seeman

For multi_enum, the values to be supplied are multi_enum option gids. For people they’re user gids.

And for reference, the complete schema for the custom field object: https://developers.asana.com/reference/custom-fields#customfield

Ok, for Posterity, here is an example for each data type:

{
  "data": {
    "custom_fields": {
      "gid_enum_custom_field": "1206014214658278",
    "gid_multi_enum_custom_field": ["1206039999820483", "1206039999820484"],
      "gid_text_custom_field": "This is a Text Field",
      "gid_number_custom_field": "99",
      "gid_person_custom_field": "1203244886871528",
      "gid_date_custom_field": {
        "date": "2022-08-18"
      }
    }
  }
}

Date-Time is still a mystery to me though. @Phil_Seeman can you help with that?

I don’t think this one is right; it should be an array like multi_enum because you can have multiple users in the people-type custom field value.

For the date custom field type:

If the value is a date only (no time of day), then the format is exactly as you’ve shown:

"gid_date_custom_field": {
        "date": "2022-08-18"
      }

If it has a time of day component, then the format is an ISO 8601 date string in UTC:

"gid_date_custom_field": {
        "date_time": "2023-12-02T02:30:00.000Z"
      }

It’s important to note that you must supply only one of date or date_time; if you send both, it will fail.

One other custom field tidbit:
Be mindful of formula fields; if you try to write to one, it will fail. A formula is a number type field but it has the property is_formula_field set to true, and also has the property is_value_read_only set to true.

Ok. This works for the most part, except I have 5 fields that throw a

{
    "errors": [
        {
            "message": "Custom field with ID 11206014696337870 is not on given object",
            "help": "For more information on API status codes and how to handle them, read the docs on errors: https://developers.asana.com/docs/errors"
        }
    ]
}

Only that field 100% is on that project. It was done in the same way as all the other fields of the same types that it for some reason doesn’t like that particular field.

This is a snippet from the get project by ID GET endpoint. As you can see. Same gid. Definitely on the project. They are all like this. They are all different types of fields, so theres no common denominator there....

{
                "gid": "1206014696337870",
                "enabled": true,
                "name": "Date - Onboarding Initiated",
                "description": "Test",
                "created_by": {

I got this sort of error when the request wasn’t formatted correctly, but it’s formatted exactly the same as the fields before and after that the call was happy with. If i take the offending fields out of the call, it posts just fine for everything else.

I can’t see any differences whatsoever.

Oh, wait. I see the leading 1 stripped off now. That’s workato’s groovy engine specialness at work.

All is good.