Skip to content

[BUG] #2349's file-growth knobs have no Settings window or MCP surface, so an alert that ships OFF cannot be enabled from any supported surface #2391

Closed

Description

@gotqn

Component

Darling

Performance Monitor Version

3.5.0

SQL Server Version

SQL Server 2022

Windows Version

Windows Server (Darling service host), Windows 11 (Viewer workstation)

Describe the Bug

[#2349] shipped the Database File Growth alert deliberately OFF. Its four knobs exist in storage - V79 adds file_growth_enabled, file_growth_rise_mb, file_growth_volume_percent and file_growth_lookback_minutes to config.config_alert_settings, and Lite carries the same four in its app settings - but they are absent from every surface an operator would actually use:

  • Darling Viewer → Settings window: no control. The alert-thresholds section has its usual neighbours (tempdb space usage, volume free space with its CRITICAL grade, monitor self-alerts, store background job cadence, version store (PVS), agent jobs, database state), and the summary line at the bottom of that section reads "Will alert when: Total CPU > 80%, blocking >= 1, deadlocks >= 1, poison waits >= 500ms avg, queries > 30min, tempdb > 80%, disk free < 10% or 5GB, PVS >= 40% of database, jobs > 3x avg, failed jobs (last 60m)" — no mention of file growth.
  • MCP get_alert_settings / update_alert_settings: no file_growth group. tempdb, low_disk, pvs and self_alerts are all present.
  • Lite Settings window: no control either.

So the only way to switch on a feature that ships OFF is a direct UPDATE against config.config_alert_settings (Darling) or hand-editing settings.json (Lite).

This also departs from the pattern [#2107] established, where every previously-hardcoded threshold was given all three surfaces at once: "six new knobs ride the store control plane, the Viewer's Settings window, and get_alert_settings/update_alert_settings, clamped on read like their siblings". #2349's knobs have the store plane only.

It looks like an unwired half rather than a deliberate omission, because the rest of the plumbing is complete and consistent with its siblings: DarlingAlertSettings already clamps the values on read (Math.Max(0, …) on the rise, [0,100] on the volume percent, [5,1440] on the lookback), and the V79 columns carry sensible NOT NULL defaults.

Steps to Reproduce

  1. Upgrade a Darling install to 3.5.0 and let the store migrate to V79.
  2. Confirm the columns landed:
    SELECT file_growth_enabled, file_growth_rise_mb, file_growth_volume_percent, file_growth_lookback_minutes FROM config.config_alert_settings WHERE id = 1;
    → returns false, 10240, 60, 60.
  3. Open the Viewer → Settings and scroll through the alert-thresholds section.
  4. Look for any file-growth control, or for file growth in the "Will alert when: …" summary line. Neither is there.
  5. Call MCP get_alert_settings. There is no file_growth group in the response, and update_alert_settings accepts no such group.
  6. The only way to enable the alert is
    UPDATE config.config_alert_settings SET file_growth_enabled = true WHERE id = 1;

Expected Behavior

The four knobs appear in the Viewer's Settings window alongside the other alert thresholds - an enable checkbox plus rise MB, volume percent and lookback minutes - and in get_alert_settings / update_alert_settings under a file_growth group, matching how every other threshold is exposed after [#2107].

Because this alert ships OFF, the enable checkbox is the important half: without it the feature is unreachable for anyone who will not write SQL against the monitoring store.

Actual Behavior

The knobs exist only as V79 store columns (Darling) and app settings (Lite). There is no Viewer control on either SKU and no MCP group, so the alert cannot be enabled or tuned from any supported surface - only by writing directly to config.config_alert_settings.

Error Messages / Log Output


Screenshots

No response

Additional Context

I asked for #2349 and want to use it - this is purely about reaching it. Enabling it today means putting a direct store UPDATE into our runbook, which is not something I would like to keep there.

Activity

  1. erikdarlingdata commented on Aug 21, 2026

    @erikdarlingdata
    Owner

    Confirmed on every point, and this one is mine — I built #2349 and shipped the store plane without the two surfaces that make it reachable.

    Verified rather than taken on trust:

    • MCP: zero occurrences of file_growth anywhere under Mcp/. No group in get_alert_settings, nothing accepted by update_alert_settings.
    • Darling Viewer: the only FileGrowth references are the schema-version probe (hasFileGrowthAlert, for the V79 banner) and an unrelated FileGrowthTargets remediation. No Settings control, and the "Will alert when: …" summary line is untouched.
    • Lite: same shape — AppAlertEngineSettings and the DuckDB read are wired, the Settings window is not.

    And your read on why it looks unwired rather than deliberate is exactly right. DarlingAlertSettings already clamps all four the way their siblings are clamped:

    public bool FileGrowthEnabled          => _config.Alerts.FileGrowthEnabled;
    public int  FileGrowthRiseMb           => Math.Max(0, _config.Alerts.FileGrowthRiseMb);
    public int  FileGrowthVolumePercent    => Math.Clamp(_config.Alerts.FileGrowthVolumePercent, 0, 100);
    public int  FileGrowthLookbackMinutes  => Math.Clamp(_config.Alerts.FileGrowthLookbackMinutes, 5, 1440);

    That is the tell: the half that is hard was done, and the half that makes it usable was not.

    The #2107 comparison is the fair one to hold this to — "six new knobs ride the store control plane, the Viewer's Settings window, and get_alert_settings/update_alert_settings". #2349 shipped one of the three. Worse than a knob that is merely awkward to reach: this alert ships OFF by design, so the enable checkbox is not a convenience, it is the only door in. Shipping it without one meant shipping a feature you asked for in a state where you cannot turn it on without writing SQL at the monitoring store. You are right not to want that in a runbook, and I would not want it in mine.

    Fixing it in that order, MCP first, because that is the one that gets the UPDATE out of your runbook soonest — a file_growth group on both tools, clamped on read like its siblings. Then the Viewer's Settings window on both SKUs, including the "Will alert when: …" summary, which is its own small bug: a summary that silently omits an enabled alert is worse than no summary.

    Not going to pretend this is anything other than an unfinished feature. Thanks for the precise report — the file-by-file inventory meant I could confirm it in one pass instead of hunting.

  2. erikdarlingdata commented on Aug 21, 2026

    @erikdarlingdata
    Owner

    Fixed on dev in #2392 — thanks for the report, @gotqn, and for holding it against the #2107 precedent. That was the right standard: #2349 shipped the store plane and stopped, which for an alert that ships OFF meant a hand-written UPDATE against config_alert_settings was the only supported way to turn on a feature someone had asked for.

    All three surfaces now carry the four knobs:

    • MCP — get_alert_settings reports a file_growth group; update_alert_settings accepts enabled, rise_mb, volume_percent, lookback_minutes.
    • Darling Viewer Settings — the control row plus seed/save/parse/gate/restore-defaults, and the Will alert when: summary, which previously could omit an alert that was enabled and able to fire.
    • Lite Settings — the same row against its App.Alert* statics, and the four writes into settings.json.

    The service side needed nothing: StoreConfigProvider has selected and read all four columns since #2349. The gap was only ever the surfaces a user can reach.

    Two guards went in with it, both aimed at the class of mistake rather than this instance. One derives the column count from AlertSettingsSelectSql and the ordinals from the reader and asserts they agree, because every field on that record is positional — a column inserted anywhere but the end silently re-maps everything after it and usually still compiles. The other pins that Lite's SaveAlertSettings writes every static it assigns; that method copies controls into statics and then statics into JSON, and skipping the second line is invisible in manual testing because the setting takes effect immediately and only reverts on the next launch.

    Write bounds match the engine's clamps exactly, pinned by a test that reads both files, so the tools can't accept a value the engine quietly rewrites on read. Zero stays valid on rise_mb and volume_percent because #2349 uses zero to disable a gate — a floor of 1 would have removed the rise-only and level-only configurations.

    Two adjacent gaps this turned up are filed separately rather than folded in: #2393 (three settings keys Lite loads but exposes nowhere) and #2394 (Lite's MCP reports 4 alert groups to Darling's 48 and cannot write any).

    Closing against dev; this reaches a build at the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions