What This Table Is

The sys_report table stores the complete definition of every report in your instance. This includes list reports, chart reports, and pivot tables created through the Reporting module. Each record defines what data to query, how to filter it, how to group it, and how to visualize the results.

The Reporting module owns this table and uses it to generate both interactive reports and scheduled report runs. When a user clicks "Create Report" or modifies an existing report, they're creating or updating a sys_report record. The system then uses this definition to query the target table and format the results according to the specified chart type and grouping rules.

This table doesn't extend any parent table—it's a standalone table. However, it has a child relationship with sys_report_color for chart color definitions and sysauto_report for scheduled report executions. Each report can reference any table in the system through the table field, making this a central registry of all reporting activity.

At scale, expect thousands of records in large enterprises. Performance is generally good for querying report metadata, but be careful when programmatically creating many reports—each record triggers multiple Business Rules that validate the report definition and create dependent records.

When You'll Script Against This Table

You'll most commonly script against sys_report in Script Includes that programmatically create or clone reports, Business Rules that validate report configurations, and Scheduled Script Executions that audit or clean up unused reports. You'll also query it in UI Actions and Client Scripts when building custom report management interfaces.

Standard report_admin role is required for full CRUD operations, though users can read their own reports. The table respects standard ACLs, but also has additional Business Rules that enforce report-specific security like preventing users from creating reports on tables they can't read.

Common scripting patterns:

  • Clone existing reports for new teams or departments with modified filters
  • Audit report usage by correlating with syslog_transaction data
  • Programmatically update report filters when table schemas change
  • Create standard report sets during application installation or updates
  • Validate report definitions before deployment across instances
  • Convert report filters from XML format to human-readable conditions
  • Bulk update chart types or styling across multiple related reports

Table Gotchas

⚠️

The `filter` field stores conditions as encoded XML, not readable GlideRecord syntax. You can't simply search for "state=1" in filters—you need to decode the XML or use GlideFilter APIs to parse conditions.

  • The table field stores the table name as a string, not a table reference. This means no referential integrity—reports can reference deleted or renamed tables.
⚠️

Chart configuration in `chart_type` and chart-specific fields can become invalid if you change the underlying report type. Always validate chart compatibility when modifying existing reports.

  • The report_type field uses choices that aren't obvious: "table" means list report, "chart" means chart report, and "pivot" means pivot table.
  • Performance trap: avoid querying by filter field contents—this triggers full table scans. Use table, sys_created_by, or report_type for indexed queries.
⚠️

Creating reports programmatically can fail silently if the target table doesn't exist or the user lacks read access to it. Always validate table accessibility before creating report records.

  • The list_field_name field becomes important for pivot tables—it defines which field values become columns, but it's ignored for regular list and chart reports.
Free Newsletter

Enjoying this? Get one deep-dive per week.

Join 1,000+ ServiceNow pros — scripts, GlideRecord patterns, Flow Designer techniques, and career moves. Free.

No spam · Unsubscribe anytime

The sysauto_report table is your most frequent join—it stores scheduled executions of reports and references sys_report records through the report field. You'll join these when tracking report usage, debugging failed scheduled runs, or auditing which reports are actively used versus just created.

The pa_dashboards and pa_widgets tables frequently reference reports for dashboard widgets. When building dashboard management tools or tracking where specific reports are displayed, you'll need to query these tables alongside sys_report. The sys_user_group table also comes into play frequently since many reports are shared with specific groups rather than individuals.

You'll also regularly query sys_dictionary when validating that report field references are still valid after schema changes. Since reports store field names as strings, you need to cross-reference with the dictionary to ensure those fields still exist on the target table. This is especially important in environments where custom fields get added and removed frequently.