affaan-m/ECC · error · Error

Unknown panel: ${selectedPanel}. Valid panels: ${Array.from(

Error message

Unknown panel: ${selectedPanel}. Valid panels: ${Array.from(VALID_PANELS).join(', ')}

What it means

Thrown by renderDashboard when options.panel is set to a value not in VALID_PANELS (success-rate, failures, amendments, versions). A null/undefined panel renders all panels, so only a non-null unknown string triggers this.

Source

Thrown at scripts/lib/skill-evolution/dashboard.js:353

    throw new Error(`Invalid now timestamp: ${now}`);
  }

  const dashboardOptions = { ...options, now };
  const records = tracker.readSkillExecutionRecords(dashboardOptions);
  const skillsById = health.discoverSkills(dashboardOptions);
  const report = health.collectSkillHealth(dashboardOptions);
  const summary = health.summarizeHealthReport(report);

  const panelRenderers = {
    'success-rate': () => renderSuccessRatePanel(records, report.skills, dashboardOptions),
    'failures': () => renderFailureClusterPanel(records, dashboardOptions),
    'amendments': () => renderAmendmentPanel(skillsById, dashboardOptions),
    'versions': () => renderVersionTimelinePanel(skillsById, dashboardOptions),
  };

  const selectedPanel = options.panel || null;
  if (selectedPanel && !VALID_PANELS.has(selectedPanel)) {
    throw new Error(`Unknown panel: ${selectedPanel}. Valid panels: ${Array.from(VALID_PANELS).join(', ')}`);
  }

  const panels = {};
  const textParts = [];

  const header = [
    'ECC Skill Health Dashboard',
    `Generated: ${now}`,
    `Skills: ${summary.total_skills} total, ${summary.healthy_skills} healthy, ${summary.declining_skills} declining`,
    '',
  ];

  textParts.push(header.join('\n'));

  if (selectedPanel) {
    const result = panelRenderers[selectedPanel]();
    panels[selectedPanel] = result.data;
    textParts.push(result.text);

View on GitHub (pinned to 01e15490f0)

Solutions

  1. Use one of: 'success-rate', 'failures', 'amendments', 'versions'.
  2. Omit options.panel (or pass null) to render every panel.
  3. If you need a custom panel, the panelRenderers map inside renderDashboard must be extended in source — there is no plugin hook.

Example fix

// before
renderDashboard({ panel: 'overview' });
// throws: Unknown panel: overview. Valid panels: success-rate, failures, amendments, versions

// after
renderDashboard({ panel: 'success-rate' });
Defensive patterns

Strategy: validation

Validate before calling

const VALID_PANELS = new Set(['success-rate','failures','amendments','versions']);
const panel = opts.panel && VALID_PANELS.has(opts.panel) ? opts.panel : null;
renderDashboard({ ...opts, panel });

Type guard

function isValidPanel(p) {
  return p == null || ['success-rate','failures','amendments','versions'].includes(p);
}

Try / catch

try {
  renderDashboard({ panel });
} catch (err) {
  if (/Unknown panel/.test(err.message)) renderDashboard({ ...opts, panel: null });
  else throw err;
}

Prevention

When it happens

Trigger: Calling renderDashboard({ panel: 'summary' }), renderDashboard({ panel: 'health' }), or any panel name outside the four valid keys. The error message lists the valid set.

Common situations: Using a panel name from an older/newer version where panels were renamed; typo; assuming a panel exists that was never implemented; copy-paste from docs that named a planned-but-unshipped panel.

Related errors


AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13). Data as JSON: /api/errors/5ee116c365f177e0. Report an issue: GitHub.