---
title: "The form showed Texas. The record had no state."
description: "A screen flow swapped typed address fields for the Address component with Google address lookup. The suggestion filled Street, City, State and ZIP on screen, the deploy succeeded, every test passed, and the Lead saved with StateCode blank. What the lookup actually returns in province and country, how to map it to State and StateCode, and why an update needs the code alone."
source: "https://noconaconsulting.com/blog/flow-address-component-statecode-blank/"
---

# The form showed Texas. The record had no state.

_Build log · Doorvana · Garage door manufacturing & service_

A screen flow swapped typed address fields for the Address component with Google address lookup. The suggestion filled Street, City, State and ZIP on screen, the deploy succeeded, every test passed, and the Lead saved with StateCode blank. What the lookup actually returns in province and country, how to map it to State and StateCode, and why an update needs the code alone.

Nocona Consulting · November 6, 2026 · 7 min read

Someone types the first few characters of a street into a search box, picks the suggestion that matches, and watches the form fill itself in. Street, City, State, ZIP. Texas, right there on the screen. They save.

The record had no state. Nothing on the screen said so, the deploy had succeeded, and every automated test in the project was green.

This is how that happened, and the two lines of mapping that fixed it.

## Swapping typed fields for address search

At [Doorvana](https://noconaconsulting.com/work/) every hand-keyed Lead is created through a screen flow, `New_Service_Lead`, which overrides the Lead New action. (Why that is the only way in is [its own post](https://noconaconsulting.com/blog/screen-flow-allowfinish-next-button/).) Until this week the flow asked for the job-site address as separate text inputs. Typing an address into four boxes is slow, and the person doing it is usually on the phone with a homeowner.

Version 12 replaced them with the standard **Address component**, `flowruntime:address`, with address lookup switched on:

force-app/main/default/flows/New\_Service\_Lead.flow-meta.xml

```xml
<fields>
    <name>Property_Address</name>
    <extensionName>flowruntime:address</extensionName>
    <fieldType>ComponentInstance</fieldType>
    <inputParameters>
        <name>addressLabel</name>
        <value><stringValue>Job Site Address</stringValue></value>
    </inputParameters>
    <inputParameters>
        <name>showAddressLookup</name>
        <value><booleanValue>true</booleanValue></value>
    </inputParameters>
    <inputParameters>
        <name>addressLookupLabel</name>
        <value><stringValue>Search Address</stringValue></value>
    </inputParameters>
    <inputParameters>
        <name>country</name>
        <value><stringValue>United States</stringValue></value>
    </inputParameters>
    ...
</fields>
```

The component’s outputs are `street`, `city`, `province`, `postalCode` and `country`, and the flow’s Create Records element maps them onto the Lead. The org has **State and Country/Territory Picklists** enabled, which means every standard address has two state fields: `State`, the full name, and `StateCode`, the two-letter picklist value. That pairing has [bitten this project before](https://noconaconsulting.com/blog/lead-state-vs-statecode-restricted-picklist/), so the first draft was careful about it. It was careful in the wrong direction.

## The assumption in the first draft

The first Draft version assumed the component’s `province` would be a state code. It kept `province` only when it was two letters long, and mapped that to `StateCode`:

New\_Service\_Lead, first Draft of v12 (reconstructed)

```xml
<formulas>
    <name>State_Code_To_Save</name>
    <dataType>String</dataType>
    <expression>IF(LEN(TRIM({!Property_Address.province})) = 2,
  UPPER(TRIM({!Property_Address.province})), "")</expression>
</formulas>
<!-- Create_Lead -->
<inputAssignments>
    <field>StateCode</field>
    <value><elementReference>State_Code_To_Save</elementReference></value>
</inputAssignments>
```

That reads as defensive: if the value is not a clean code, write nothing rather than write something a restricted picklist will reject. And it would have been fine, if the lookup returned codes.

It does not. The first on-screen run picked a Google suggestion, the form showed Texas, and the saved Lead had `StateCode` blank. In this build, **the address lookup put the full state name in `province`**. The two-letter guard did exactly what it was written to do. It threw the state away, quietly, on every address that came through search.

The lookup filled province with the state name, not the code

In this build, choosing an address suggestion in `flowruntime:address` put the full state name, such as `Texas`, in `province`. A mapping that assumes a two-letter code and drops anything else will drop every looked-up state. Check what the component actually returns before you decide which field it maps to.

## The fix: map both shapes

The flow now takes either shape. A two-letter value goes to `StateCode`, anything longer goes to `State`, and each formula writes blank when the value belongs to the other field:

force-app/main/default/flows/New\_Service\_Lead.flow-meta.xml

```xml
<formulas>
    <description>Two-letter province value goes to StateCode.</description>
    <name>State_Code_To_Save</name>
    <dataType>String</dataType>
    <expression>IF(OR({!Is_Supply}, {!Is_TBD}), "",
  IF(LEN(TRIM({!Property_Address.province})) = 2,
    UPPER(TRIM({!Property_Address.province})), ""))</expression>
</formulas>
<formulas>
    <description>A full state name, which is what the address lookup returns, goes to State.</description>
    <name>State_Name_To_Save</name>
    <dataType>String</dataType>
    <expression>IF(OR({!Is_Supply}, {!Is_TBD}), "",
  IF(LEN(TRIM({!Property_Address.province})) = 2,
    "", TRIM({!Property_Address.province})))</expression>
</formulas>
```

And `Create_Lead` maps both:

force-app/main/default/flows/New\_Service\_Lead.flow-meta.xml

```xml
<inputAssignments>
    <field>State</field>
    <value><elementReference>State_Name_To_Save</elementReference></value>
</inputAssignments>
<inputAssignments>
    <field>StateCode</field>
    <value><elementReference>State_Code_To_Save</elementReference></value>
</inputAssignments>
```

(`Is_Supply` and `Is_TBD` are there because a dealer buying doors has no job site, and a new subdivision lot may not have a street address yet. Hidden inputs can keep old values when the user goes back, so every saved value is guarded.)

This was confirmed two ways in the browser: once through the lookup, and once by typing an address and choosing the state from the dropdown. Both Leads were read back with `State` Texas and `StateCode` TX.

## Country had the same assumption

The component’s `country` input had been set to `US`. On screen, the Country picklist sat on `--None--`. Setting the input to `United States` selected it. Same mistake, other field: a code where the component wanted a name.

Set the Address component's country input to the name

In this build, `country` set to `US` left Country on `--None--`, and `United States` selected it. Set it and look at the screen; do not assume the input takes the same value the `CountryCode` picklist stores.

## The same field, on update, behaved the other way

The Address component turns up a second time in the same flow, as an optional Billing Address for business clients, and that value has to reach the converted Account. The after-save conversion flow, `Lead_Convert_Build_Property_And_Household`, writes it onto an Account that already exists by the time it runs. So this is an **update**, not an insert.

The obvious move was to write the name to `BillingState`, which is what the component returns. On the update, supplying `BillingState` with a blank `BillingStateCode` left the code null. The state disappeared again, by the opposite route.

So the conversion flow converts the name to a code and writes only `BillingStateCode`:

force-app/main/default/flows/Lead\_Convert\_Build\_Property\_And\_Household.flow-meta.xml

```xml
<formulas>
    <description>The address component returns the full state name. Written as a code only,
      because on an update a blank code clears the state even when a name is supplied.</description>
    <name>Billing_State_Code</name>
    <dataType>String</dataType>
    <expression>IF(LEN(TRIM({!$Record.Billing_State__c})) = 2,
  UPPER(TRIM({!$Record.Billing_State__c})),
  CASE(TRIM({!$Record.Billing_State__c}),
    "Alabama", "AL",
    "Alaska", "AK",
    ...
    "Texas", "TX",
    ...
    "Wyoming", "WY",
    ""))</expression>
</formulas>
```

A `CASE` over fifty-one names is not elegant. It is explicit, it runs in a flow with no Apex, and an unrecognised value produces blank rather than a value the restricted picklist rejects.

On update, write the state code, not the name

Supplying `BillingState` with a blank `BillingStateCode` on an update left the code null. When updating an address on an existing record with State and Country/Territory Picklists on, convert to the code and write `BillingStateCode` alone.

## Why nothing automated caught it

The deploy succeeded, and every automated check was green. Neither fact says anything about this bug, because **an Apex test cannot run a screen flow**. `SalesReworkTest` can insert Leads, convert them and assert on what comes out, but the step that went wrong is the one between a person picking a suggestion and the Create Records element. That step only exists on screen.

The only check that found it was the one that sounds too simple to bother with: run the screen, save, open the record, and read every field back. Not the page; the fields. The page showed an address. The `StateCode` field was empty.

Read the saved record, not the form

For any screen flow that maps a component’s output onto a record, test by saving and reading the record back field by field. A wrong mapping deploys clean, activates, and passes every Apex test that drives the records behind it.

## The red herring: the search box that was not there

One thing slowed this down. The first screenshot of the new screen had no Search Address box at all, which looked like a missing setting: `showAddressLookup` not taking effect, or a Maps setting not enabled in the org. It was neither. The box was in the page’s element tree and had simply rendered late. A second look found it.

Worth knowing before you go digging through `MapsAndLocationSettings`: if the lookup field is missing from a screenshot, check whether it is missing from the page.

## What was verified, and what was not

-   The lookup path and the typed path with the state dropdown were each run on screen, saved, and read back. Both held `State` Texas and `StateCode` TX.
-   The country input was confirmed on screen with both values.
-   The billing update was found in a validation run of the conversion tests and fixed by writing the code alone.
-   What the component returns for addresses outside the United States was not tested.

## Practical summary

-   `flowruntime:address` with `showAddressLookup` true put the full state name in `province` in this build. Do not assume a code.
-   Map a two-letter `province` to `StateCode` and anything longer to `State`. Saving a Lead that way gave both fields on read-back.
-   Set the component’s `country` input to `United States`, not `US`.
-   On an update to an existing address, a name with a blank code left the code null. Convert the name and write the `...StateCode` field alone.
-   Apex cannot run a screen flow. Save on screen and read the record back.
-   If the Search Address box is missing from a screenshot, look again before you change settings.

-   Flow
-   Screen flows
-   Address
-   State and Country/Territory Picklists
-   Lead
-   Testing

Disclosure: Doorvana's owner is also a co-owner of Nocona Consulting. This is a real engagement between two separate companies, but not an arm's-length one — and not an independent reference. [More on the work page](https://noconaconsulting.com/work/).

## FAQ

### What does the flowruntime:address component return in province when the address lookup is used?

In this build, choosing a Google suggestion in the Address component with showAddressLookup set to true put the full state name, such as Texas, in the component's province output, not the two-letter code. A flow that assumed a code and mapped province to StateCode only when it was two letters long saved the record with no state at all.

### How should a screen flow map the Address component to State and StateCode?

Handle both shapes. Send a two-letter province value to StateCode and a longer value to State, leaving the other blank. With State and Country/Territory Picklists enabled, a Lead created that way, from either the address lookup or a typed address with the state dropdown, was read back with State Texas and StateCode TX.

### Why does the Address component show --None-- for Country when the country input is US?

In this build the component's country input did not accept the code. Setting it to US left the Country picklist on --None--, while setting it to United States selected the country. Set the input to the country name and confirm it on screen.

### Why does updating BillingState not change the state on an Account with State and Country/Territory Picklists?

On an update, supplying BillingState with a blank BillingStateCode left the state code null rather than deriving it from the name. Convert the name to a two-letter code and write only BillingStateCode when updating an existing record.

### Can an Apex test catch a mapping error in a screen flow?

Not directly. Apex cannot run a screen flow, so a test can only exercise the records and automation behind it. A screen flow that maps a component output to the wrong field deploys cleanly and passes every Apex test. Run the screen and read the saved record back field by field.
