affaan-m/ECC · error · Error
Unknown control-pane action: ${actionId}
Error message
Unknown control-pane action: ${actionId} What it means
Thrown by buildControlPaneAction at scripts/lib/control-pane/actions.js:97-100 when actionId is not a key in the ACTION_DEFINITIONS Map. The control pane exposes a fixed set of ECC2 graph actions — sync-knowledge, recall-knowledge, graph-sync, open-dashboard — each mapped to a cargo invocation against the ecc2 workspace. Unknown ids are rejected before any cargo command is constructed. The function is called both directly from the HTTP server's POST /api/actions/:id route (server.js:271) and from buildControlPaneActions which iterates all known keys.
Source
Thrown at scripts/lib/control-pane/actions.js:99
const text = String(value);
if (text.length === 0) return "''";
if (/^[A-Za-z0-9_./:=@%+-]+$/.test(text)) return text;
return `'${text.replace(/'/g, `'\\''`)}'`;
}
function commandLineFor(action) {
return [
`cd ${shellQuote(action.cwd)}`,
'&&',
shellQuote(action.command),
...action.args.map(shellQuote),
].join(' ');
}
function buildControlPaneAction(actionId, options = {}) {
const definition = ACTION_DEFINITIONS.get(actionId);
if (!definition) {
throw new Error(`Unknown control-pane action: ${actionId}`);
}
const repoRoot = path.resolve(options.repoRoot || process.cwd());
const cwd = path.join(repoRoot, 'ecc2');
const limit = normalizeLimit(options.limit);
const query = String(options.query || '').trim();
const args = definition.args({ limit, query });
const action = {
id: actionId,
label: definition.label,
description: definition.description,
command: 'cargo',
args,
cwd,
executable: definition.executable,
};
return {View on GitHub (pinned to 01e15490f0)
Solutions
- Use one of the known ids: sync-knowledge, recall-knowledge, graph-sync, open-dashboard.
- Call GET /api/snapshot or buildControlPaneActions() to enumerate the live action ids for your version.
- If you need a new action, register it in the ACTION_DEFINITIONS Map at actions.js:5-72 (label, description, args factory, executable flag).
- Note: even valid ids that are non-executable (open-dashboard, executable:false) return a 400 from the server rather than running — see server.js:277-285.
Example fix
// before
fetch('http://127.0.0.1:8765/api/actions/sync', { method: 'POST' });
// after
fetch('http://127.0.0.1:8765/api/actions/sync-knowledge', { method: 'POST', body: '{}' }); Defensive patterns
Strategy: validation
Validate before calling
const KNOWN = new Set(['sync-knowledge', 'recall-knowledge', 'graph-sync', 'open-dashboard']);
function assertKnownAction(actionId) {
if (!KNOWN.has(actionId)) throw new Error(`Unknown control-pane action: ${actionId}`);
return actionId;
} Type guard
function isControlPaneActionId(value) {
return typeof value === 'string'
&& ['sync-knowledge', 'recall-knowledge', 'graph-sync', 'open-dashboard'].includes(value);
} Prevention
- Enumerate actions via buildControlPaneActions() or GET /api/snapshot rather than hardcoding ids in clients.
- Validate client-supplied action ids through isControlPaneActionId before POSTing.
- When renaming or removing an action, keep a deprecated alias for a release cycle.
When it happens
Trigger: POST /api/actions/sync to the control-pane server (truncated/misspelled id); POST /api/actions/recall-knowledge%2Fextra (path-traversal-ish id); a UI button wired to a stale action id after an upgrade that renamed or removed an action; calling buildControlPaneAction('refresh', {}) from a script.
Common situations: Custom UI dashboards referencing actions that were renamed across versions; URL-encoded typos; clients POSTing the action label ('Sync Knowledge') instead of the id ('sync-knowledge'); attackers probing arbitrary action ids against the loopback server.
Related errors
- Invalid ${name} value: expected a path
- Invalid --port value: ${portValue}
- Expected JSON response from control pane:
- create request: %w
- ECC_PROJECT_DIR must be a child path within /workspace.
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/7d1e295a8ad707aa.
Report an issue: GitHub.