{"record":{"id":"fcce7ff0a30d65cc","repo":"octobercms/october","slug":"inspector-surface-unique-id-should-be-defined","errorCode":null,"errorMessage":"Inspector surface unique ID should be defined.","messagePattern":"Inspector surface unique ID should be defined\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"modules/backend/assets/foundation/controls/inspector/inspector.surface.js","lineNumber":40,"sourceCode":"\n    var Base = $.oc.foundation.base,\n        BaseProto = Base.prototype\n\n    /**\n     * Creates the Inspector surface in a container.\n     * - containerElement container DOM element\n     * - properties array (array of objects)\n     * - values - property values, an object\n     * - inspectorUniqueId - a string containing the unique inspector identifier.\n     *   The identifier should be a constant for an inspectable element. Use\n     *   $.oc.inspector.helpers.generateElementUniqueId(element) to generate a persistent ID\n     *   for an element. Use $.oc.inspector.helpers.generateUniqueId() to generate an ID\n     *   not associated with an element. Inspector uses the ID for storing configuration\n     *   related to an element in the document DOM.\n     */\n    var Surface = function(containerElement, properties, values, inspectorUniqueId, options, parentSurface, group, propertyName) {\n        if (inspectorUniqueId === undefined) {\n            throw new Error('Inspector surface unique ID should be defined.')\n        }\n\n        this.options = $.extend({}, Surface.DEFAULTS, typeof options == 'object' && options)\n        this.rawProperties = properties\n        this.parsedProperties = $.oc.inspector.engine.processPropertyGroups(properties)\n        this.container = containerElement\n        this.inspectorUniqueId = inspectorUniqueId\n        this.values = values !== null ? values : {}\n        this.originalValues = $.extend(true, {}, this.values) // Clone the values hash\n        this.idCounter = 1\n        this.popupCounter = 0\n        this.parentSurface = parentSurface\n        this.propertyName = propertyName\n\n        this.editors = []\n        this.externalParameterEditors = []\n        this.tableContainer = null\n        this.groupManager = null","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/backend/assets/foundation/controls/inspector/inspector.surface.js#L22-L58","documentation":"The second ReportDataPaginationParams constructor check: `$currentPage` must be zero or a positive integer (page indexes are zero-based here, as the docblock 'current page index' indicates). Negative page values would produce negative offsets, so the constructor throws this ApplicationException for anything below 0.","triggerScenarios":"Constructing with `(int) get('page') - 1` when the request page is 0 or missing, yielding -1; page inputs that allow negative numbers; arithmetic on page numbers that underflows before the call.","commonSituations":"Converting 1-based UI page numbers to 0-based indexes and forgetting the floor; defaulting page to -1 as an 'unset' sentinel; tests passing -1.","solutions":["Clamp the page index to >= 0 before constructing, e.g. `max(0, (int) $request->input('page', 1) - 1)`.","Use a plain default of 0 for the first page instead of -1 sentinels.","Validate user-supplied page parameters (integer, >= 1 in 1-based form) at the request boundary."],"exampleFix":"// before\n$page = (int) array_get($params, 'page', 0) - 1;\nnew ReportDataPaginationParams(20, $page);\n\n// after\n$page = max(0, (int) array_get($params, 'page', 1) - 1);\nnew ReportDataPaginationParams(20, $page);","handlingStrategy":"validation","validationCode":"// Convert and clamp 1-based UI pages to 0-based indexes\n$pageParam = (int) request()->input('page', 1); // 1-based from the UI\n$currentPage = max(0, $pageParam - 1);          // 0-based index, never negative\n$params = new \\Dashboard\\Classes\\ReportDataPaginationParams($perPage, $currentPage);","typeGuard":"/**\n * @param mixed $value\n * @returns {boolean}\n */\nfunction isValidPageIndex($value)\n{\n    return is_int($value) && $value >= 0;\n}","tryCatchPattern":null,"preventionTips":["Convert 1-based page inputs with max(0, page - 1) so page 0 cannot underflow to -1.","Never use -1 as an 'unset page' sentinel; use 0 for the first page.","Validate page query parameters as integers at the request boundary."],"tags":["october-cms","dashboard","reports","pagination","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}