Challenge Not Yet Complete

Salesforce Trailhead “Challenge not yet complete” most common causes

Ah, Spring is in the air. So are arms, as people new to Salesforce throw them up during Trailhead challenges where they can’t seem to get the hands-on part to pass even though they see the result they expect.

The Trailhead modules and Superbadges are so well organized and written, it may seem like there is an instructor reviewing you submissions, but that would not be practical, profitable, or in the spirit of a cloud platform. The scoring is done by automated tests that are checking that things match exactly as the instructions provided.

The most common cause is that the learner has mis-typed a value provided, usually the API name (i.e., my_variable__c). Runner up to this is the experienced user who is new to Trailhead and uses their own naming conventions rather than following the instructions (been there, done that).

The third common cause is that the module content was updated but the test was not (doesn’t happen that often, but you can tell when there are a bunch of questions on the Trailhead Community about the same problem).

Here’s another I often see. Some of the lessons are re-used between modules and trails, or were once in a different order. Regardless of how it got to be, the instructions may say to create a new playground when one has already been created for the module or trail, and work done previously is required to continue.

A couple of similar issues to the above I have also seen is when there are steps described in the lesson content and the challenge assumes these steps were done in the playground. Alternatively, it is sometimes not clear to new Trail Blazers that the same playground should be used throughout a given module or trail, or they inadvertently select to create a new playground or select the wrong playground. Personally, I use a collection of Developer orgs instead of playgrounds to make it easier to go back and find something I had done previously, but I don’t recommend that for most beginners.

This is not an exhaustive list. If you got through it and still haven’t seen Assessment Complete! +500 points, read through the module from the start as if you had never seen it before. Depending on your input processing style, you may want to wait a day or two. Or post a request for help on Trailhead and be sure to include a link to the lesson and module in your request. And feel free to tag @Scott S Nelson.

HTH

Facebooktwitterredditlinkedinmail
© Scott S. Nelson
Select Query in Workbench

How to re-assign Salesforce object ownership in bulk

Here is a question I see frequently in the Trailhead Community: How do you re-assign the ownership of objects in bulk? I’m sure there is an app to make this easier, and I suggest you look in the AppExchange if the policy for your org is to use apps first. And I know there are other solutions, this is just one that I find quick and easy because I don’t have to give it too much thought.

Accounts before Owner Change

First: Always try it in a sandbox first and test the results before doing it in production.

Second first, locate the user id of the person who’s object owners ship you want to change from. From their user page (or just copying the link), grab the object ID from the URL.

Find Object Owner

Copy Object ID
Copy Object ID

Now open Salesforce Workbench in another tab, login and navigate to Queries > SOQL queries. If you are adept at SOQL, create a query to pull all of the object you want to re-assign based on the user id. If you are not comfortable writing your own SOQL or just feeling lazy, use Workbench to help create the query:

Select Query in Workbench

The key values you want are the object ID and the owner ID, though adding a Name field to check the values can be helpful. Be sure to select View as Bulk CSV then run the query. Save the resulting file. I recommend naming it something that is meaningful to you rather than accepting the long string produced by default. Open in your favorite CSV editor to see the object and owner ids.

Next, get the user ID of the new owner(s) the same way you did for the current owner. In the CSV file, change the OwnerId value as desired.

For safety reasons, delete all columns from the csv file except Id and OwnerId, then save it with a different name as a CSV file.

Object and Owner IDs only

Back in Workbench, go to Data > Update. Select the object type and click the Choose File button and select the file you just created with the new OwnerId(s), then click Next.

On the mapping screen the values should already be mapped. Check that only the ID and OwnerId are mapped and click the Map Fields button. If there are many records, check the “Process records asynchronously via Bulk API” option on the resulting page then Confirm Update. Note that if rules were changed since the records were created you may have errors that will require fixing the records before they can be updated.

Could happen if rules changed since created

And in list view:

After Owner Change

Facebooktwitterredditlinkedinmail
© Scott S. Nelson
Package with Zipper

A simple Salesforce Package cheat sheet

As an IT consultant, I frequently change technologies and project roles. The frequent shift of focus is great for staying interested, engaged, and marketable. The downside is that many mental-muscle-memory tasks fade or never take root with long gaps between repetitions. One example is XSLT, which I have had to re-learn three times because it is not difficult to learn but only find I need it every five to seven years. Another example is various Linux commands, which I will post on my blog so that I can find them quickly when needed.

An additional technique I use, when available, is little cheats where the broad strokes are easy to remember and help prompt my memory for the details. The example of this I want to share today is creating Salesforce Unlocked Packages.

Before I start, it is important to understand that for a true package-management and -deployment strategy there is a lot more involved than just the ability to create a package. A package strategy requires thinking about how the org is used, who the stakeholders are, how many teams contribute to code and metadata within the org and how different their focuses are, and clear roadmap for an enterprise architecture with agreements on the direction and commitment to sustainable governance model. This post is just about being able to take something built in one org and being able to deploy it into another org as either a consulting starter, a demo set, or a shared feature.

In this example, I built a useful little Flow demo that guides CSRs in first searching for a contact before creating them to reduce duplication while following standard procedures for customer contact.

Flow module in action

It is a good component to keep handy as a starting point for clients that need a similar feature, so I want to be able to easily manage it in source control and distribute it to other orgs. Or I may want to share it with other developers for enhancements. In either case, I don’t work hands-on with packages to easily remember how to construct them. No fear! I do remember how to create unmanaged packages, which is a good start. However, it has been a while since I built this component, so looking at the list of flows does not make it clear to me what is what:

Call in contact flow package definition

I could guess, based on the names, but it is safer to be sure, so I go to the flow itself and look at the Properties to find the API Name:

Flow version properties

Components can have dependencies. Sometimes it is necessary to track them down and can require some test deployments to be sure all have been captured. In this case, the implementation is straight-forward, and Salesforce still finds a component that I had forgotten was involved:

Package component dependencies

Now that there is a package definition in the Salesforce org, I want to be able to move it to Github where I can work with it. The next step is to go to https://workbench.developerforce.com and navigate to Migration\Retrieve and select to extract the package by name:

Using Workbench to extract package

This will produce a zip file of the package components. To make these useful, set up a Visual Studio Code project for Salesforce (see if How to set up a Salesforce development environment you need help with this part). Now unzip the package into a folder name “unpackaged” at the same level as [PROJEC_PATH] and run the following command:

sf project convert mdapi --root-dir ../unpackaged --output-dir force-app

If the above paths were laid out correctly, you will see an output showing the components added to your project. Otherwise, check your folder layout and naming conventions and try again. At this point, it is useful to replace the default /manifest/package.xml with the one in the root of the unzipped package from Workbench (the following step assumes this). Finally, test that you can push the package contents to another org with:

sf project deploy start --target-org [USERNAME] --manifest ../[PROJECT_PATH]/manifest/package.xml --test-level RunLocalTests --wait 100

Once all components are deployed, you should see them in your org (they may not be enabled):

sf cli deployment
Package deployed

In this case, the flows require activation before they can be used. Post deployment steps will depend on your components.

Finally, add your project to source control. The project used in this article can be found at https://github.com/ssnsolutionist/Call-in-Contact-Flow-main.

Some of the steps above included commands from a cheat-sheet I maintain at https://github.com/ssnsolutionist/trailhead1/blob/master/sfdx-cli-common-commands.md

09-08-24 Revision Notes:
  1. The cheat sheet linked above is out of date. I’m working on it, mostly by having Perplexity.ai re-write them for me as I need them.
  2. Originally published as a Logic20/20 Insight article, the editors there later stripped out the screen shots, so publishing the full version here.
Facebooktwitterredditlinkedinmail
© Scott S. Nelson
Method does not exist or incorrect signature

Salesforce Deployments when Other People’s Code Fails Validation

As a cloud architecture consultant I have always applauded Salesforce for requiring 75% test coverage for deployments. I just wish that it was a minimum per class rather than an average per org. Why? Because things change and over time the average in production can come down to the point where adding a new change set that is at 75% when averaged with what is in production drops the total average. Because of this, I have set the standard for my team as 95%, which always got us through this issue until recently.

Another team had run a deployment that removed methods previous tests relied on. When my change set was validated, I was surprised to see the following error:

Method does not exist or incorrect signature
Method does not exist or incorrect signature

What was most vexing about this is that none of the classes in error were touched by my change set. Usually this can be fixed with a recompile, but not this time. What to do? Well, someone else had gotten a deployment through (there are multiple teams working in the org), so I knew there had to be some solution. And there was! Sparing you the dozen things I tried that did not work, here is the solution:

Run specified tests

And the proof:

Ready for Quick Deployment
Facebooktwitterredditlinkedinmail
© Scott S. Nelson

Get Hands-on with VS Code, Salesforce DX and Packages

(Originally published at Logic 20/20 as SFDX, VSCode, and deploying from a package the editors stripped out all of the links, rendering it an entirely different post. This is the original version.)

While I do not immediately dislike new tools, I do struggle with adopting them when I find nothing wrong with the old ones. And then I delay learning them until I’m forced to, which is the case of Visual Studio code for Salesforce (they are no longer supporting the Eclipse IDE and abandoned the DX extension for Eclipse before DX went GA) and Git (because that is the way the dev world has gone). I find the best way to learn new tools is to write about how to learn them, so here we go.

(In the spirit of working in a low code platform, we will also see how much of this I can do with just links to existing documentation…)

If you haven’t already, Install Salesforce Extensions for VS Code.

Then Enable Dev Hub in Your Org and Enable Second-Generation Packaging (note that while 2GP is beta as of this writing, this is required to enable first generation Unlocked Packages which is GA).

Next…Well, that didn’t take long. I cannot find a stand-alone URL for creating an SFDX project, so I’m going to steal a section from a Trailhead lesson (because it is as much typing to say what not to do as it is to re-create it here):

  1. Open VS Code.
  2. From the menu, select View | Command Palette.
  3. In the command palette search box, enter [PROJECT_NAME].
  4. Select SFDX: Create Project.
  5. Use the same name as your GitHub repo, then click Enter.
  6. Click Create Project.
  7. Create a .gitignore file to ignore hidden directories:
    1. Hover over the title bar for the DX project. then click the New File icon.
    2. Enter .gitignore. [check if it already exists and just edit if so]
    3. In the text editor, indicate to ignore these two hidden files:
.sfdx
.vscode

To foster good habits, I will set up a github repo to store this project in (though following a full lifecycle will be another article) by following the excellent documentation at https://help.github.com/en/github/importing-your-projects-to-github/adding-an-existing-project-to-github-using-the-command-line and add the project to the repository.

Now go do some work in Salesforce. For example purposes, let’s do the Build a Simple Flow project.

After you complete the project, follow the instructions to Create and Upload an Unmanaged Package, skipping the Upload part. I named the project TH_Flow_Project, which you don’t have to, I only mention that as I will use that text in the example commands.

Salesforce provides a nice reference to Create a Salesforce DX Project from Existing Source.  I have some additional thinking around how to go about this part, so I will end the approach of linking to references and switch to my own approach. If you followed the last link and stopped here, you won’t learn anymore about the Salesforce DX capabilities, but you may miss out on some of my shortcuts and wit. With that said…

Authorize the org you created the flow in with the following:

sfdx force:auth:web:login –setalias <MY_SOURCE_ALIAS> –instanceurl <MY_ SOURCE_ORG_URL>

Example:

sfdx force:auth:web:login --setalias TH-ORG02 --instanceurl https://infa-ca-wav-dev-ed.my.salesforce.com/

A bit late to mention, but if you are using a Developer org, I highly recommend to Set Up My Domain. Trailhead orgs already have one. If you haven’t, you can probably leave off the instanceurl parameter and it should pick it up from the default configuration for your project (YMMV). Otherwise use the URL that you login to your org with.

Next, download the package using the following:

sfdx force:mdapi:retrieve -r ../ -p <PACKAGE_NAME> -u <USERNAME>, ex:

sfdx force:mdapi:retrieve -r ../ -p TH_Flow_Project -u scott@trailh2.org

Let’s break that down just a bit. The first part is the base command to retrieve (sfdx force:mdapi:retrieve). The -r parameter determines where the downloaded zip file will be located. The example uses a relative path indicating the folder above the DX project. As a best practice, I recommend always staying in the project directory inside the VSC terminal, with all commands base on being relative to that location. This way you can maintain a list of commonly-used commands that will be re-usable across all projects. The downloaded file name is always unpackaged.zip.

The files need to be unzipped before they can be used (someone should make a feature request for the convert command to work on zip files instead of having to unpack them first). In Linux the relative command is:

unzip ../unpackaged.zip -d ../

Now we add the files from the package to our project using the relative path command:

sfdx force:mdapi:convert -r <PATH_TO_UNZIPPED_PACKAGE> -d <PATH_TO_[/force-app]>, ex:

sfdx force:mdapi:convert -r ../TH_Flow_Project -d force-app

Now all of the files from your package are part of your project.

To add this to your target org, first authorize that org as done previously for the source org, i.e.:

sfdx force:auth:web:login –setalias <MY_TARGET_ALIAS> –instanceurl <MY_ TARGET_ORG_URL>

Example:

sfdx force:auth:web:login --setalias TH-ORG02 --instanceurl https://infa-ca-wav-dev-ed.my.salesforce.com/

And (almost) finally, deploy the updates from your project to the target org with:

sfdx force:source:deploy -u <TARGET_USERNAME> -x <PATH-TO-PACKAGE.XML>

sfdx force:source:deploy -u apex@theitsolutionist.com -x ../TH_Flow_Project/package.xml

(Another feature recommendation is to have an alias option instead of only the username.)

And finally (this time for real!) look in your list of flows to see the flow installed in your target org.

Of course, you are doing this with a throw-away org, right? Because I forgot to mention that deploying will over-write any existing components with the same name.

One final note. We used the package.xml from the downloaded package for the sake of simplicity. Once the package import is validated, you will want to combine the package.xml from the download with the package.xml in your project located in the manifest folder of your project.

The project created from the writing of this article can be found at https://github.com/ssnsolutionist/trailhead1

Facebooktwitterredditlinkedinmail
© Scott S. Nelson