[SalesForce] INVALID_ID_FIELD when upserting an attachment through Bulk API

The situation is as follows:

In my Salesforce org, I have a contact, let's call it Humpty Dumpty, and I'd like to attach a file to it, let's call it cooking.txt, but there are some rules:

  • If there attachment is already there, overwrite it.
  • If the attachment isn't there, attach it.

For that purpose, I'm using Bulk API and upserts.

request.txt looks like below:

<?xml version="1.0" encoding="UTF-8"?>
<sObjects xmlns="http://www.force.com/2009/06/asyncapi/dataload" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <sObject>
        <ContentType>text/plain</ContentType>
        <Description/>
        <Name>cooking.txt</Name>
        <Body>#cooking.txt</Body>
        <Id>00P_blah_blah</Id>
        <ParentId>003_blah_blah</ParentId>
    </sObject>
</sObjects>

00P_blah_blah is the ID of the attachment attached to my contact, Humpty Dumpty. My intention is to use it as the external ID field in upsert, so that, if an attachment with that ID already exists, it'll be updated, and if not, it'll be inserted.

In my Java code, I also do this:

job.setOperation(OperationEnum.upsert);
job.setExternalIdFieldName("Id");

where job is an instance of JobInfo.

However, this fails, and the error is:

Errors(fields=null, message=invalid record id, statusCode=INVALID_ID_FIELD)

Anyone knows what could be the reason for this, and how to fix it?

Thanks all!

Update 1

00P_blah_blah and 003_blah_blah are fake IDs of course. In reality, I'm using 18-character IDs.

Update 2

Depending on whether the attachment already exists, and fields I send in, here's how it works:

  • attachment doesn't exist, input has ID and ParentId -> error as above
  • attachment doesn't exist, input has ParentId -> success (attachment is created)
  • attachment exists, input has ID and ParentId -> success (attachment is updated)

Update 3:

I get the same when using SOAP instead of Bulk API:

// Example in Java
SObject obj = new SObject("Attachment");
obj.setField("Id", "id goes here");
obj.setField("ContentType", "text/plain");
obj.setField("Name", "milkshake");
obj.setField("Description", null);
obj.setField("Body", IOUtils.toByteArray(new FileInputStream("/path/to/recipes/milkshake.txt")));
obj.setField("ParentId", "parent id goes here");
partnerConnection.upsert("Id", new SObject[] { obj });

Best Answer

You can't set the Id for a create - If you're creating it, SF will provide the ID. If you've given it an ID for an upsert, it'll error out if the record doesn't exist (since you can't set the ID)

If you're providing the ID, where are you getting it from? (if it's from another SF instance, this post has some info:

UPDATE

This SF API doc explains more about the error: Core Data Types Used in API

Here is the relevant text:

INVALID_ID_FIELD

The specified ID is correctly formatted, but is not valid, for example, it is an ID of the wrong type, or the object it identifies no longer exists.

Related Topic