octobercms/october · error · Error

Key property (${keyProperty}) value should be a string. Prop

Error message

Key property (${keyProperty}) value should be a string. Property: ${this.propertyDefinition.property}

What it means

Once a definition name is known, initDash verifies it against the controller's dash configuration (from `dashGetConfig()`, typically `config_dash.yaml` or the `$dashConfig` array) using dashHasDefinition, which checks whether the config object has a top-level property named after the definition. If that key does not exist, this ApplicationException is thrown with the requested definition name substituted for :field.

Source

Thrown at modules/backend/assets/foundation/controls/inspector/inspector.editor.objectlist.js:489

            return true
        }

        if (this.currentRowInspector === null) {
            return true
        }

        var data = this.currentRowInspector.getValues(),
            keyProperty = this.propertyDefinition.keyProperty

        if (data[keyProperty] === undefined) {
            throw new Error('Key property ' + keyProperty + ' is not found in the Inspector data. Property: ' + this.propertyDefinition.property)
        }

        var keyPropertyValue = data[keyProperty],
            keyPropertyTitle = this.getKeyProperty().title

        if (typeof keyPropertyValue !== 'string') {
            throw new Error('Key property (' + keyProperty + ') value should be a string. Property: ' + this.propertyDefinition.property)
        }

        if ($.trim(keyPropertyValue).length === 0) {
            $.oc.flashMsg({text: 'The value of key property ' + keyPropertyTitle + ' cannot be empty.', 'class': 'error', 'interval': 3})
            return false
        }

        var selectedRow = this.getSelectedRow(),
            tbody = this.getTableBody(),
            dataRows = tbody.querySelectorAll('tr[data-inspector-values]')

        for (var i = 0, len = dataRows.length; i < len; i++) {
            var dataRow = dataRows[i],
                rowData = JSON.parse(dataRow.getAttribute('data-inspector-values'))

            if (selectedRow == dataRow) {
                continue
            }

View on GitHub (pinned to b608633a7e)

Solutions

  1. Add the definition as a top-level key in your dash config, e.g. in config_dash.yaml: `reports:` followed by its properties.
  2. Or correct the name at the call site to match an existing key (watch spelling and case).
  3. For dynamic dashboards, register the definition at runtime with `$this->dashRegisterDefinition('reports', [...])` before rendering.

Example fix

# config/config_dash.yaml
# before
main:
  widgets: [...]

# after (dashRender('reports') was requested)
main:
  widgets: [...]
reports:
  widgets: [...]
Defensive patterns

Strategy: validation

Validate before calling

// Validate the definition against the config before using it
$definition = post(\Dashboard\Behaviors\DashController::PARAM_DEFINITION) ?: 'main';
if (!$this->dashHasDefinition($definition)) { // public helper on the behavior
    throw new NotFoundException('Unknown dashboard: '.$definition);
}
return $this->dashRender($definition);

Try / catch

try {
    $this->dashRender($name);
} catch (ApplicationException $e) {
    if (str_contains($e->getMessage(), 'does not contain a definition')) {
        // the name is valid syntax but absent from config — add the YAML key or fix the name
    }
}

Prevention

When it happens

Trigger: Calling `dashRender('reports')` when the YAML only defines `main:`; posting `_dash_definition=oldname` after a config refactor renamed the key; typos or case differences between the render call and the config key.

Common situations: Renaming definitions in config_dash.yaml without updating views and AJAX payloads; adding a second dashboard to the config and misspelling the key; environments where the YAML file differs (config file not deployed).

Related errors


AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21). Data as JSON: /api/errors/41b8b2b7e6344a24. Report an issue: GitHub.