High-Impact Bug Patterns in Salesforce Custom Objects & How to Fix Them
QA
5 MIN READ
July 28, 2026
![]()
A QA engineer’s field guide to the bugs standard objects never have.
Standard Salesforce objects like Lead, Contact, Account, and Opportunity come with years of battle-testing baked right in. Millions of orgs, millions of edge cases, millions of bug reports have already shaped how they behave. Custom objects don’t have that luxury. Every field, validation rule, and relationship on a custom object is designed and deployed by a human usually in a hurry, and often without dedicated QA.
Below is an engineering guide to the most common invisible, high-impact bugs found in custom objects. We’ll explain with exact test cases needed to catch them before your users do, along with real examples pulled from the field, including patterns we’ve seen repeatedly while testing managed-care and healthcare Salesforce implementations.
Millions of users have tested standard objects. Your sprint team has tested custom objects. That’s the gap your QA strategy needs to close.
Silent Killers of Custom Object Deployments
Before diving into specific test cases, it’s vital to recognize the five primary ways custom object defects present themselves. Each one is dangerous precisely because it doesn’t announce itself.
- Silent Failures — Bad data saves without throwing an error or alert. Users remain completely unaware that something went wrong until a downstream report or integration breaks.
- Rule Stacking — Multiple validation rules interact unexpectedly when triggered simultaneously, locking users out of records that should be perfectly valid.
- Profile Blind Spots — Bugs that are only visible to specific user profiles. Admins who test exclusively using the System Administrator profile miss them entirely.
- Deployment Gaps — Custom object schemas that fail to migrate cleanly between sandboxes and production environments, especially when metadata dependencies are missed.
- Automation Drift — Flows, Apex triggers, and validation rules quietly fall out of sync with the schema as the object evolves sprint over sprint, until nobody remembers why a rule exists.
Quick example: On a managed-care Salesforce implementation, a custom “Plan Enrollment” object accumulated 14 validation rules over six sprints. By sprint seven, two rules silently contradicted each other for a rare combination of Plan Type and Enrollment Source — nobody noticed until a regional sales team reported that 3% of enrollments simply couldn’t be saved.
Deep Dive: The Top 9 Bug Categories & Test Cases
1. Validation Rule Conflicts on the Same Object
Risk level: Critical
A single custom object can easily accumulate 10 to 20 validation rules, each authored independently. When they run together, they can contradict one another, creating “impossible-to-save” states where no combination of field values can satisfy all rules simultaneously.
Test Case ID: TC-CUSTOM-001 (Critical)
Objective: Verify that a record can be saved in an approved status with its authorization date populated without contradictory validation rules blocking the save.
Test Steps:
- Open a record in “Pending” status.
- Set Status to “Approved” and leave the Authorization Date blank, then save — note the error.
- Set Authorization Date to today, keep Status as “Pending”, then save — note the error.
- Set BOTH Status to “Approved” and Authorization Date to today, then save.
Expected Result: Setting both fields allows the record to save successfully. Individual field omissions show clear, non-contradictory validation messages.
How to catch it: Build a validation rule matrix. List every rule and the field-value combinations that trigger it. Test at least three combinations involving overlapping conditions, paying special attention to any two rules referencing the same field.
2. Required Field Logic Dependent on Record Type
Risk level: High
Custom objects often serve multiple business purposes via record types. A field required for one record type may be completely irrelevant for another. When required-field logic isn’t record-type-aware, users get blocked by mandatory fields that make no sense in their scenario.
Test Case ID: TC-CUSTOM-002 (High)
Context: Consider an organization with “Direct Purchase” and “Insurance Covered” record types. The Managed Care Plan field should only be mandatory for insurance-covered orders.
Test Steps:
- Create a record with Record Type “Direct Purchase” and leave Managed Care Plan blank, then save.
- Create a record with Record Type “Insurance Covered” and leave Managed Care Plan blank, then save.
Expected Result: Step 1 saves successfully. Step 2 throws a validation error stating the field is required.
The fix: Never use the field-level “Required” checkbox on a custom object if the field is only conditionally required. Deploy a conditional validation rule scoped by RecordType.DeveloperName instead.
3. Lookup Relationship Failures and Orphaned Records
Risk level: High
A lookup field pointing to a deleted parent record does not leave a broken reference. By default, Salesforce clears the lookup field to null on the child record. This creates an “orphan” — a child record silently disconnected from its parent. The field appears blank in the UI, and downstream automations, reports, and integrations that assume the field is populated fail with null-reference errors, incorrect filtering, or skipped records.
Test Case ID: TC-CUSTOM-003 & 004 (High / Medium)
Context: An assignment record links a patient to a specific provider. If a provider is removed from the network or suspended, the lookup logic must handle it gracefully.
Test Steps (Parent Deletion):
- Create an assignment record linked to an active provider.
- Delete the parent provider record.
- Open the assignment record and confirm the lookup field has been cleared to blank.
- Trigger any associated flows, Apex, or reports and verify they handle the null lookup without errors, silent failures, or record exclusions.
Test Steps (Lookup Filters): Search for a suspended provider while creating an assignment. Without strict lookup filters, suspended or retired providers still appear in the dropdown, leading to erroneous assignments. Verify the filter is configured as Required, not Optional — optional filters can be bypassed.
Prevention tip: For high-risk lookups, configure the lookup deletion option to “Don’t allow deletion of the lookup record that’s part of a lookup relationship.” This blocks the orphaning at the source. Alternatively, use a Master-Detail relationship, but note that cascade delete removes all child records entirely, which may be a worse outcome than orphaning for audit-sensitive data.
4. Field-Level Security (FLS) Gaps Exposing Sensitive Data
Risk level: High · Compliance
Custom objects frequently store highly sensitive business data or protected information. Field-Level Security (FLS) controls visibility, but because it’s configured per profile across frequent deployments, gaps are inevitable. Worst of all, FLS failures are completely silent — there is no error message when a field is simply visible to the wrong profile.
Test Case ID: TC-CUSTOM-005 (High / Compliance)
Objective: Verify that sensitive financial or insurance fields are hidden from standard sales users and visible only to compliance or billing specialists. Test effective access — profile and all permission sets, not the profile in isolation.
| Profile Type | Expected Visibility |
|---|---|
| Sales Representative | Completely Hidden |
| Billing Specialist | Visible & Editable |
| Sales Manager | Visible (Read-Only) |
| Compliance Auditor | Visible (Read-Only) |
Note: If field-level audit history is required for compliance, enable Field History Tracking on the sensitive field at the object level. This is an org-wide, per-field setting — it is not configured per profile or permission set and captures changes regardless of which user edits the field.
Test Steps:
- Log in as (or use “Login As” for) a user representing each persona above.
- Open a record and inspect the page layout, list views, and reports for the sensitive field.
- Attempt to query the field via the API or a report as the restricted persona.
- Review the user’s effective field access via Setup → Object Manager → Field → “View Field Accessibility,” or via a permission-analysis report, to confirm no permission set silently grants access.
5. Picklist Value Mismatches Breaking Flows
Risk level: High
Inactive values left on existing records, dependent picklists losing their controlling values, and automated flows referencing a renamed picklist value by its old label are incredibly common defects that slip through without dedicated picklist testing. Picklist values have both a label (what users see) and an API name (what automation compares against). Renaming the label is safe; changing the API name is dangerous. Salesforce provides no dependency check to show where an individual picklist value is referenced.
Test Case ID: TC-CUSTOM-006 & 007 (High)
Real-world failure A — Dependency stranding: When a controlling picklist value is deactivated, existing records retain the old controlling and dependent values, and the record becomes a dead end. When a user edits the controlling field, the original combination can no longer be re-selected, and the dependent value becomes invalid or is cleared on that edit. The state is unreproducible through the UI, forcing users into a value combination the business never intended.
Test steps: 1) Create a record using controlling value “X” and dependent value “Y.” 2) Deactivate controlling value “X.” 3) Reopen the record and confirm both values still display. 4) Edit the controlling field, save, and observe that the original combination is unrecoverable and the dependent value is invalidated. 5) Verify any flows or validation rules referencing “Y” still behave correctly for untouched legacy records.
Real-world failure B — Stale API name reference: A record-triggered flow checks if a status equals “In Review” to fire an email alert. The picklist value is renamed to “Under Review” mid-sprint, but the flow is left pointing to the old string. It fails silently, resulting in dozens of missed notifications to an Insurance approvals queue.
Test steps: 1) Identify every Flow, Validation Rule, and Apex class comparing against the picklist’s API names. 2) Change or replace a value’s API name in a sandbox. 3) Run each automation path and confirm whether decisions still match. 4) Separately rename only a label and confirm automations are unaffected.
6. Record Type & Page Layout Mismatches
Risk level: High
Record types and page layouts share a complex, many-to-many relationship assigned per profile. Mapping a layout incorrectly means users see fields that don’t apply to their context, miss critical fields they need, or gain access to restricted actions. A field or action removed from a layout remains reachable via the API, reports, and list views unless Field-Level Security and object permissions restrict it — never rely on a layout to hide sensitive data.
Test Case ID: TC-CUSTOM-008 (High)
Objective: Verify that every profile × record type combination presents the correct page layout, with the intended fields, sections, required-field markers, and actions — and nothing belonging to another persona’s layout.
Test Steps:
- Build a layout assignment matrix listing every profile, every record type, and the layout intended for each intersection.
- Log in as a representative user of each profile.
- Create and edit a record of each record type available to that profile.
- Verify the fields, sections, related lists, and buttons displayed match the matrix exactly. Flag both missing elements and extra ones.
- Confirm layout-level required fields behave as intended for that persona.
Expected Result: Each persona sees precisely the layout defined in the matrix for their profile and record type, with no bleed-through of fields or actions from other layouts.
The root cause: Testers evaluated the feature using a System Administrator account, which bypasses page layout restrictions entirely. Testing as an admin therefore validates the wrong layout, and every profile-specific mis-mapping ships undetected. Profile-specific testing would have caught this immediately.
7. Rollup Summary Field Miscalculations
Risk level: Medium
Rollup summary fields aggregate values from child records (COUNT, SUM, MIN, MAX) based on specific filter criteria. These fields exist only on Master-Detail relationships — they cannot be created on lookup relationships. Teams needing a rollup across a lookup must build it with Flow, Apex, or a tool like DLRS, each of which introduces far more timing, bulkification, and recalculation bugs than the native feature. An incorrect filter condition, a null child value, or a timing issue during record deletion can silently corrupt the aggregate calculation.
Test Case ID: TC-CUSTOM-009 (Medium)
Objective: Verify that a rollup summary field returns the correct aggregate across creation, update, deletion, and undeletion of child records, including null-value and filter-excluded children.
Test Steps:
- Create a parent with three child records having known values (e.g., 100, 200, 300) and confirm the SUM shows 600.
- Add a child whose aggregated field is null and confirm the total remains 600 — the null child must be excluded, not treated as zero.
- Add a child that fails the rollup filter criteria and confirm it is excluded from the aggregate.
- Edit a child so it now meets the filter criteria and confirm the rollup increments immediately.
- Delete a child and confirm the rollup decrements; undelete it from the Recycle Bin and confirm the value is restored.
- Reparent a child to a different master and confirm both parents’ rollups adjust correctly.
- Bulk-load 200+ children via Data Loader and compare the rollup against an independently computed total.
Expected Result: The aggregate matches the independently calculated value at every step, null children never contribute, filter-excluded children never appear in the total, and reparenting updates both sides.
Real-world failure: When a child record is deleted, the parent rollup field occasionally caches a stale value until a subsequent manual edit forces recalculation — Salesforce rollup fields don’t always recalculate in real time during certain bulk deletion operations.
Mitigation: Test the full CRUD cycle on child records, evaluate how null values interact with formulas, and mitigate edge cases with scheduled rollup recalculation jobs.
8. Apex Trigger Order & Recursion on Custom Objects
Risk level: High
Custom objects that accumulate multiple triggers over time — one from the original build, others bolted on by later integrations — are highly exposed to execution-order bugs. Salesforce doesn’t guarantee the order in which multiple triggers on the same object fire, and a trigger that updates its own object can recurse into itself if recursion guards are missing.
Test Case ID: TC-CUSTOM-010 (High)
Context: An Insurance Calculation object has one trigger that recalculates the Insurance amount and a second, separately deployed trigger that logs an audit record whenever the amount changes.
Test Steps:
- Perform a bulk update of 200+ Insurance records in a single Data Loader batch.
- Verify the calculated amount matches expected values for every record.
- Verify exactly one audit record is created per genuine change — not per trigger execution.
Real-world failure: The audit trigger fires twice for the same change because the calculation trigger updates the record mid-transaction without a static recursion flag, doubling audit records and, in one case, pushing a bulk batch of 200 records past the 150-DML governor limit and failing the entire transaction.
How to catch it: Always test bulk operations (200+ records) rather than single-record saves, and check debug logs for duplicate DML statements or unexpectedly high SOQL/DML counts.
9. Sharing Rules & OWD Misconfiguration
Risk level: High · Compliance
Custom objects default to whatever Organization-Wide Default (OWD) is set when they’re created — often Public Read/Write unless someone deliberately locks it down. The OWD travels with the object’s metadata (sharingModel), so a deployment can silently overwrite a tightened production setting. Sharing rules can only grant access beyond the OWD, never restrict it — over-exposure always traces back to a too-open baseline or a too-broad rule. As custom sharing rules are layered on later to support specific roles, it’s easy to leave a gap where a role sees more records than intended, or a criteria-based sharing rule silently stops matching after a picklist rename.
Test Case ID: TC-CUSTOM-011 (High / Compliance)
Objective: Verify that the account record is visible only to the assigned care team and their managers, not to the entire Sales division.
Test Steps:
- Confirm the object’s OWD in Setup matches the documented target (e.g., Private).
- Log in as a member of the assigned care team and confirm record access.
- Log in as that member’s manager and confirm access — this validates Grant Access Using Hierarchies is enabled.
- Log in as a low-privilege user from an unrelated role (Sales division) and confirm the record is invisible in list views, reports, search, and via direct URL.
- Verify the test users hold no View All Data / Modify All Data or object-level “View All” permission, which would bypass sharing and invalidate the test.
- If a criteria-based rule references picklist values, change one value in a sandbox and confirm the rule still matches.
- If the object is the detail side of a Master-Detail, note that its OWD is locked to Controlled by Parent — test the parent’s sharing instead.
Expected Result: Access is granted exclusively through the intended path (ownership, team sharing rule, role hierarchy), and the unrelated-role user gets “insufficient privileges” on every access route.
Real-world failure: OWD for the custom object was left at Public Read Only after a sandbox refresh overwrote a tighter production setting, exposing patient-adjacent account records org-wide until a routine access review caught it three weeks later.
How to catch it: After every sandbox refresh and every deployment, log in as a low-privilege test user from an unrelated role and confirm they cannot see records outside their sharing rules.
Summary Matrix: Bugs at a Glance
| # | Bug Category | Risk Level | How to Catch It |
|---|---|---|---|
| 1 | Validation rule conflicts | Critical | Build a rule matrix; test overlapping conditions |
| 2 | Required field by record type | High | Test each record type; avoid field-level checkboxes |
| 3 | Lookup failures & orphaned records | High | Test parent deletion; set deletion restriction on high-risk lookups; verify filters are required, not optional |
| 4 | FLS gaps in sensitive fields | High · Compliance | Test effective access (profile + permission sets) per persona; include API/Apex-level checks, not just UI |
| 5 | Picklist value mismatches | High | Audit all Flows, rules, and Apex when picklists change |
| 6 | Record type/layout errors | High | Maintain a layout matrix; never test solely as Admin |
| 7 | Rollup summary miscalculations | Medium | Test full CRUD on children; explicitly test nulls; force mass recalculation after loads or filter edits |
| 8 | Trigger order & recursion | High | Bulk-test 200+ records; check debug logs for duplicate DML |
| 9 | Sharing rules & OWD gaps | High · Compliance | Diff deployed sharingModel against production baseline; re-test as low-privilege user post-deployment |
The Master QA Checklist for Custom Objects
Before signing off on your next custom object deployment, ensure your team ticks every box on this checklist:
- Document every validation rule per custom object in a centralized matrix before testing begins.
- Test at least 3 overlapping validation rule combinations per object.
- Avoid setting fields as required at the field level — use conditional validation rules instead.
- Test all lookup fields against parent deletion, null values, and custom filter criteria.
- Manually verify FLS for every sensitive field across all active profiles after each deployment.
- When a picklist value changes, programmatically audit every Flow, rule, and Apex class referencing it.
- Maintain a dedicated Record Type × Profile × Layout matrix and spot-check it post-deployment.
- Test rollup summary fields through a complete CRUD lifecycle, including inserting null child values.
- Flag custom objects with multiple Apex triggers as technical debt and test them for non-determinism under bulk load.
- Verify OWD and sharing rules by logging in as a low-privilege user immediately after every deployment.
- Always test using profile-specific users — never a System Administrator — for layout and FLS validation.
- Document the exact error message text for every failed test to easily map which rule fired.
Conclusion
The bug you don’t test for is the one your users will find in production. On a custom object, that risk is multiplied because everything was built by hand.
Custom objects are the soul of a tailored Salesforce implementation. They are exactly where the unique business logic that differentiates your company lives. But that uniqueness is also their ultimate vulnerability. Unlike standard objects, they have no massive global community knowledge base or ecosystem of millions of testers who have already surfaced the edge cases.
![]()
Author
About the Author Editorial Team The Ksolves Editorial Team includes certified Salesforce experts, Big Data engineers, AI/ML specialists, Zoho consultants, and experienced technology writers focused on delivering clear, actionable insights for modern businesses. With hands-on experience across Salesforce, Big Data platforms, AI/ML solutions, application development, software testing, and Zoho ERP/CRM, the team publishes practical guides, real-world use cases, and industry updates that support smarter decisions and faster growth. Every article is created to solve business challenges, guide technology adoption, and keep organizations aligned with evolving digital ecosystems.
Share with