Skip to main content
New tool CRON Expression Builder — preview next run times before you schedule Apex. Open the builder →
A 3D vault icon representing a protected custom setting in a Salesforce development environment.
Apex

Protected Custom Settings: Fixing Null Values from LWC

Protected Custom Settings return null in LWC because of the scope the Protected modifier applies. Here is what it restricts, and which Apex patterns still get the data to your component.

The short answer

A Protected Custom Setting restricts access to the scope of the package that owns it, so a null in your LWC is usually that restriction working rather than a bug. Wrap retrieval in a service class that null-checks on the server, switch to Custom Metadata Types if the data need not be hidden, or check the user's access.

Key takeaways 'Protected' means the setting is restricted to the owning namespace. An LWC outside that scope gets null by design. Never assume getOrgDefaults() hands back a populated object. Handle the null in your Apex controller so the front end does not crash. When configuration has to be read across packages or namespaces, Custom Metadata Types are usually a cleaner architectural choice than Protected Custom Settings. Check that the running user holds the metadata permissions needed to read the settings you are asking for. Put a controlled Apex service layer between your Lightning components and your configuration objects, and the access stays maintainable and secure.

Introduction

Custom Settings are a lightweight way to hold application-wide configuration, so most of us reach for them early. Marking one 'Protected' buys a specific kind of security: the data stays hidden from managed packages and external orgs. Then a Lightning Web Component queries that setting and the values come back null.

Why the value comes back null

Marking a Custom Setting as protected restricts access to that setting to the scope of the package that owns it. The null you are staring at is usually that restriction doing its job, not a platform bug.

When your LWC calls an @AuraEnabled Apex method to retrieve those values, the context depends on whether your code is part of a soql-in-loops-security-review-impact-for-managed-packages/" class="auto-link">managed package. Develop outside the namespace that owns the setting, or fragment the visibility somewhere in your org structure, and the system returns null silently instead of exposing the configuration.

The common pitfalls

  • The component sits outside the managed namespace that owns the setting.
  • The LWC runs in a context that lacks the permissions to see the private settings.
  • Now and then getOrgDefaults() caches values wrongly inside a user session, after the hierarchy or scope has changed.

Step 1: check the retrieval pattern first

Before you debug the null, confirm you are using the right retrieval method. Plenty of us have called getInstance() with the wrong Id, or never checked whether the record exists at all.

The standard, secure way to fetch these settings in Apex:

public with sharing class ConfigService {
    @AuraEnabled(cacheable=true)
    public static Map<String, String> getProtectedSettings() {
        // Fetch the setting record
        My_Protected_Setting__c settings = My_Protected_Setting__c.getOrgDefaults();
        
        Map<String, String> configMap = new Map<String, String>();
        
        // Always check for null before accessing fields
        if (settings != null) {
            configMap.put('ApiEndpoint', settings.API_Endpoint__c);
            configMap.put('Timeout', String.valueOf(settings.Timeout__c));
        }
        
        return configMap;
    }
}

If that method returns null for your LWC, you are almost certainly looking at an access violation caused by the 'Protected' scope.

Step 2: architecture options for protected data

If your architecture needs LWC to reach sensitive data, there are three paths out of the null.

Rather than exposing the settings directly, create a service layer class that runs without sharing if the business requirements permit, or manage the visibility explicitly. A service class keeps the retrieval logic in one place and puts the null checks on the server, so the LWC never receives undefined data.

2. Custom Metadata Types (CMDT)

If the configuration does not strictly need hiding from managed packages, and is not subject to user-specific overrides, consider switching to Custom Metadata Types. CMDTs are queryable through SOQL and behave more predictably when Apex reads them for an LWC.

3. Permission set validation

Check that the user running the LWC has the access. Even with the setting marked 'Protected', a component running in that user's context needs the 'View All Custom Settings' permission, or whatever specific access your org setup calls for, or the payload arrives empty.

Step 3: debugging and validation

Stop troubleshooting from the LWC console logs alone. The problem usually hides in the Apex layer. Three checks worth running:

  1. Add a System.debug immediately after the getOrgDefaults() call. If the value is null there, the LWC is not your problem; the visibility is.
  2. Run a block of anonymous Apex as the specific user hitting the issue, using System.runAs(). That mimics the LWC execution context.
  3. If your organization uses namespaces, check that your Apex class is prefixed correctly when the custom setting belongs to that package.
// Execute as a non-admin user to verify security visibility
User u = [SELECT Id FROM User WHERE Profile.Name = 'Standard User' LIMIT 1];
System.runAs(u) {
    My_Protected_Setting__c settings = My_Protected_Setting__c.getOrgDefaults();
    System.debug('Settings found: ' + settings);
}
Newsletter

One email every Tuesday

New guides, tool updates, and the release-note changes that break things.

No spam. Unsubscribe in one click.

Comments

Loading comments...

Leave a Comment