Skip to content
NetSuite reporting

Reporting on NetSuite custom fields: why they disappear

Why NetSuite custom fields disappear from reports: store value, applies-to, field type and role access, plus how to query custbody and custcol fields.

ERPray teamUpdated 7 min read
Short answer

A NetSuite custom field is missing from your report for one of four reasons: Store Value is off, so nothing is stored to search on; the field isn't applied to the record type you're searching; the type isn't searchable as you assume; or your role can't see it. Saved searches and SuiteQL see every stored custom field; the Report Builder often does not.

Key takeaways

  • If Store Value is off, the field has no value in the database. It can be displayed and it cannot be reported on. This is the single most common cause of a 'missing' custom field.
  • The Applies To settings decide which record types carry the field. A transaction body field not applied to Invoice will never appear in an invoice search, however visible it looks on a sales order.
  • Custom field internal ids tell you where the field lives: custbody on transaction headers, custcol on transaction lines, custentity on entities, custitem on items, custrecord on custom records.
  • Multiple-select fields store a delimited list of internal ids. They cannot be joined, which makes them the worst choice for any dimension you intend to report by.
  • A sourced field with Store Value on is a snapshot taken when the record was saved. It does not update when the source record changes, and that is usually a feature, not a bug.

The complaint arrives the same way every time. Someone added a custom field to a NetSuite record eighteen months ago, everyone has been filling it in diligently since, and now that it matters for reporting it isn't in the field list. Or worse: it is in the field list, the search runs, and every row comes back blank. NetSuite custom field reporting fails in a small number of specific ways, and each one has a tell.

Six reasons the field isn't in your report

Check these in order. The first two account for most cases and both take under a minute to confirm on the custom field record itself.

  1. 1.Store Value is unchecked. With Store Value off, NetSuite computes or sources the value for display and never writes it to the database. There is nothing to search on, nothing to export, nothing in SuiteQL. The field looks completely normal on screen, which is what makes this so frustrating to diagnose.
  2. 2.The field isn't applied to the record type you're searching. The Applies To settings on a custom field control which record types get it. A transaction body field applied to Sales Order and Item Fulfilment but not Invoice is invisible in an invoice search, even though users see it on the order they're looking at.
  3. 3.You're in the Report Builder, not a saved search. The Report Builder works from a curated field list for each report type, and plenty of custom fields simply aren't offered in it. Saved searches and SuiteQL can see anything that is stored. "It's not in the report" is usually a report limitation rather than a data problem.
  4. 4.Your role can't see it. Custom fields can be restricted by role, with view or edit access set per role. If the field is restricted and your role isn't on the list, it won't appear in your search field list at all — and it will appear for the administrator who tells you the field is fine.
  5. 5.The field type isn't stored the way you expect. Inline HTML has no stored value by design. Rich Text stores markup, so exports arrive with tags in them. Long Text doesn't behave like Free-Form Text in grouping and formulas. See the table below.
  6. 6.There are two fields with the same label. Labels aren't unique; internal ids are. Two fields called "Region" on the same record, created by two different people two years apart, with 40% of records populated in one and 60% in the other, is a real and common finding. The internal id is the only thing to trust.

Field type decides what reporting is possible

Choose the field type for how the data will be reported, not for how the form should look. This is the decision that either saves or costs you a day, two years later.

Field typeWhat's storedReporting behaviour
Free-Form TextThe stringGroups, filters and sorts cleanly. The safe default for anything short.
Text Area / Long TextLonger stringsFine for display and keyword filters. Awkward to group by and limited in formulas — don't use it as a dimension.
Rich TextMarkup as well as textExports carry HTML tags. Never use it for anything you will group, compare or dedupe.
List/RecordThe internal id of the selected recordThe best choice for a dimension. Searches show the label; SuiteQL returns the id, so wrap it in BUILTIN.DF() to get the text.
Multiple SelectA delimited list of internal idsCannot be joined. Reportable only with string matching. Avoid for anything you'll slice by.
Check BoxT or FPerfectly behaved. Reports as a two-value dimension, and formulas can count it directly.
Date / DatetimeA date valueFilters and period grouping work as expected. Datetime carries a time component that will surprise a day-boundary filter.
Currency / Decimal / IntegerA numberSums and averages properly. Currency fields follow the record's currency, so mixed-currency totals need converting first.
PercentA number with percent displayCheck whether 15% is stored as 15 or 0.15 in your account before you multiply anything by it.
Inline HTMLNothingDisplay only. It will never appear in a search, a report or an export.
If a field will be a report dimension, make it List/Record or Check Box. If it will be a measure, make it numeric. Everything else is a text box you'll regret.

Body fields, line fields, and the double-count

Transactions have two kinds of custom field and mixing them up produces numbers that are wrong rather than missing. A body field lives once on the header. A column field lives on every line. Put a body field into a line-level search and its value repeats on every line — so if that body field happens to be a currency amount and someone sums it, a five-line invoice reports five times the real figure.

  • Reporting a body field on its own? Filter Main Line to true so you get one row per transaction.
  • Reporting a body field alongside line detail? Keep it as a grouping or a maximum in the summary, never a sum.
  • Reporting a line field? Main Line false, and exclude tax and shipping lines, or your line count will include rows a user never typed.
Free calculator
SuiteQL formatter

Custom field ids are long and queries that use them get unreadable fast. Paste one in to get clause breaks and consistent keyword casing back.

Reading a custom field id

The prefix on an internal id tells you where the field lives, which tells you which table it will appear on in SuiteQL. This is the fastest orientation trick in NetSuite reporting.

PrefixWhere the field livesWhere it appears in SuiteQL
custbody_Transaction body (header)A column on transaction
custcol_Transaction line / columnA column on transactionline
custentity_Entity records: customer, vendor, employee, contact, partnerA column on customer, vendor and the other entity tables
custitem_Item recordsA column on item
custrecord_Fields on custom records, and fields on other record typesA column on the customrecord_* table that owns it
custevent_CRM records such as events and casesA column on the relevant CRM table
Custom segments are a separate mechanism from custom fields — they are GL-impacting dimensions and typically carry a cseg prefix, so check yours rather than assuming they behave like custbody fields.

In a query, stored custom fields are just columns. There is no special syntax and no join required:

SELECT
  t.tranid,
  t.trandate,
  t.custbody_project_code                  AS project_code,
  BUILTIN.DF(t.custbody_delivery_region)   AS delivery_region,
  tl.custcol_line_reference                AS line_reference,
  ABS(tl.netamount)                        AS line_amount
FROM transaction t
JOIN transactionline tl
  ON tl.transaction = t.id
WHERE t.type      = 'CustInvc'
  AND t.posting   = 'T'
  AND tl.mainline = 'F'
  AND tl.taxline  = 'F'
ORDER BY t.trandate DESC
custbody on the header, custcol on the line. BUILTIN.DF() converts a List/Record id into the text a human wanted.

Multiple-select fields, and why to avoid them

A Multiple Select field stores several internal ids in one delimited string. You cannot join it to the referenced table, so every reporting approach is a workaround. String matching works if you pad the boundaries — without the padding, id 12 matches ids 120, 121 and 512:

-- Fragile but sometimes the only option
SELECT t.tranid, t.custbody_service_tags
FROM transaction t
WHERE ',' || t.custbody_service_tags || ',' LIKE '%,12,%'
Padding both ends stops partial-id matches. It still can't be grouped, counted or joined properly.

If a dimension needs to be many-valued and you need to report by it, the right structure is a child custom record — one row per record-and-value pair — which you can join like anything else. That turns an unqueryable string into a proper relation. How to query NetSuite custom records covers the naming and discovery side, and SuiteQL join examples has the join patterns.

A custom field can source its value from a related record — pulling a customer's region onto every invoice, for instance. The behaviour depends entirely on Store Value. With it off, the field displays the current value from the source and reports as empty. With it on, the value is written when the record is saved and then frozen.

That freezing is usually what you want in finance. If a customer moves from the North region to the South in March, last year's invoices should still report under North, because that's where the revenue was earned. But it does mean a field that looks like a live lookup isn't one, and re-saving a batch of old records will silently rewrite history. Decide which behaviour you want, write it down on the field's description, and stop rediscovering it every audit.

Before you add another custom field

  • Is there a standard field that does this? Class, department, location and the item hierarchy are already joined to everything and already in every report. A custom field duplicating one of them creates two versions of the truth.
  • Is it a dimension or a note? Dimensions are List/Record with a maintained list behind them. Notes are text. A free-text field used as a dimension gives you "North", "north", "Nrth" and "North " as four regions.
  • Who is allowed to leave it blank? Set it mandatory at creation or accept permanent gaps. Retrofitting completeness onto 60,000 historical records is a CSV update project, not a report fix.
  • Will it end up in a spreadsheet? Most custom-field reporting ends as an export someone reshapes. Search results move around as CSV and JSON more than anyone admits, and the CSV to JSON converter and JSON to CSV converter save the fiddly quoting step in the middle.
  • Are you about to hit a search ceiling? Custom-field reporting is where saved searches usually run out of room, because the interesting questions need formula columns over joined fields. NetSuite saved search limitations sets out where the actual limits are.

The shortcut

Diagnosing a missing custom field means checking Store Value, checking Applies To, checking role access, then working out which table the id lives on. It is entirely learnable and it is also the reason simple questions about your own data take an afternoon. builds a dictionary of your account's real fields — including the custom ones, with their types and where they're stored — so asking "revenue by delivery region for Q2" resolves to your custbody_delivery_region field, computed live, with the SuiteQL shown so you can see exactly which field it used and whether that was the one you meant.

Frequently asked questions

Why is my NetSuite custom field not showing in a saved search?

Most often because Store Value is unchecked on the field, so no value exists in the database to search. The next most likely causes are that the field isn't applied to the record type you're searching, or that role-level access on the field excludes your role. All three are visible on the custom field record itself.

What does Store Value do on a NetSuite custom field?

It controls whether the value is written to the database. With Store Value on, the value is saved with the record and can be searched, exported and queried. With it off, NetSuite only computes or sources the value for display, so the field appears normal on screen but is invisible to every reporting tool.

How do I query a NetSuite custom field in SuiteQL?

Stored custom fields are ordinary columns. Transaction header fields appear as custbody_ columns on the transaction table, line fields as custcol_ columns on transactionline, entity fields as custentity_ columns on customer or vendor, and item fields as custitem_ columns on item. Wrap List/Record fields in BUILTIN.DF() to get the label instead of the internal id.

Which NetSuite custom field types can be reported on?

Free-Form Text, List/Record, Check Box, Date, Currency, Decimal, Integer and Percent all report cleanly. Long Text and Text Area work for display and keyword filters but are awkward as grouping dimensions. Multiple Select stores a delimited id list and can't be joined. Inline HTML stores nothing at all and never appears in reports.

Why do my custom field values repeat on every line of a transaction search?

Because it is a transaction body field, which lives once on the header and is echoed onto every line of a line-level search. Filter Main Line to true if you want one row per transaction, and never sum a body field in a line-level result — a five-line invoice will report the value five times.

Do custom fields appear in NetSuite's standard reports?

Sometimes. The Report Builder works from a curated field list per report type and many custom fields aren't offered there, even when the data is stored and perfectly searchable. If a field is visible in a saved search but not in the report you're customising, that's a report limitation — build the saved search instead.

Your ERP already knows. Start asking.

ERPray computes answers like these live from your own ERP account and shows the exact query behind every number. Early access is open for NetSuite teams — free plan at launch.