Straight answer: the report type decides which objects and fields a report can ever see, and you cannot change it after the report is created. A field missing from a report is nearly always a report type problem, not a permissions problem, and the fix is a new custom report type rather than an edit to the report.
Standard and custom, and why standard runs out
Salesforce generates standard report types for every object and its common relationships. They are fine until you need something they do not join, at which point you are writing a custom one.
A custom report type does three things standard types cannot:
- Choose the join behaviour. “A records may or may not have related B records” is an outer join; “A records must have at least one related B record” is an inner join. Standard types pick one and do not tell you which.
- Add fields through lookups. Up to four levels of relationship, which is where most of the missing fields live.
- Control which fields are available at all, and which are pre-selected in a new report.
The four-object limit
A custom report type joins at most four objects, A through D, each related to the one before. That constraint is absolute and it shapes the design. If your requirement needs five, the usual answers are a formula field that pulls the value up a level, or a roll-up, or accepting two reports.
The order matters and cannot be rearranged later. Object A is the primary, and a record must exist in A to appear at all. Getting A wrong means starting over, so the first question is always “what is one row in this report”.
Why your field is missing
In order of likelihood:
- The report type does not include it. Edit the report type, Edit Layout, and drag the field into a section. Fields are not automatically added when someone creates a new custom field, which is the single most common cause.
- The field is on an object outside the four. No amount of editing fixes this.
- Field-level security hides it from the running user. Check with a different user before assuming.
- The join excludes the rows. An inner join on an object with no related records drops the parent entirely, which reads as missing data rather than a missing field.
New fields do not appear automatically
This deserves its own heading because it catches everyone. Add a custom field to Opportunity, and every standard report type gets it. Add it to an object used in a custom report type, and it appears in the report type’s field layout only if “Add fields related via lookup” or the automatic setting was configured, and often not even then.
Build it into the process: creating a field includes checking the custom report types that reference the object. Otherwise the gap is discovered by a user three months later who assumes the data is wrong.
Deployment behaviour
Custom report types are metadata and deploy normally. Two things to watch. The deployment overwrites the field layout entirely, so a field someone added by hand in production disappears. And a report type referencing a field that is not in the same deployment fails, which makes ordering matter.
Reports themselves are also metadata, and a report whose report type is not present fails to deploy with an error that names the report rather than the missing type.
Deactivating rather than deleting
A custom report type can be set to In Development, which hides it from everyone except administrators. That is the right first step when retiring one, because deleting it deletes every report built on it. The reports do not become orphaned. They are removed.
Performance
The report type decides the join, and the join is most of the cost. An outer join across four objects on large tables is expensive no matter what filters the report applies. If a report is slow and the filters are already selective, the report type is the next place to look, and the diagnosis is the same elimination described in why your report is slow.
Frequently asked
Can I change a report’s type? No. Create a new report on the correct type and rebuild it. There is no conversion.
Why can I not find my custom object? The object needs “Allow Reports” enabled in its definition. It is off by default on objects created through some paths.
Do custom report types respect sharing? Yes. They control which fields are available. The running user still sees only records they have access to.
