{"record":{"id":"6cda2af96e9db80b","repo":"nanocoai/nanoclaw","slug":"no-approval-handler-registered-row-dropped","errorCode":null,"errorMessage":"No approval handler registered — row dropped","messagePattern":"No approval handler registered — row dropped","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/modules/approvals/response-handler.ts","lineNumber":108,"sourceCode":"  }\n\n  if (!(await transitionPendingApprovalStatus(approval.approval_id, 'pending', 'approved'))) return;\n\n  // Approved — dispatch to the module that registered for this action.\n  const notify = (text: string): Promise<void> =>\n    writeSessionMessage(session.agent_group_id, session.id, {\n      id: `appr-note-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n      kind: 'chat',\n      timestamp: new Date().toISOString(),\n      platformId: session.agent_group_id,\n      channelType: 'agent',\n      threadId: null,\n      content: JSON.stringify({ text, sender: 'system', senderId: 'system' }),\n    });\n\n  const handler = getApprovalHandler(approval.action);\n  if (!handler) {\n    log.warn('No approval handler registered — row dropped', {\n      approvalId: approval.approval_id,\n      action: approval.action,\n    });\n    await notify(`Your ${approval.action} was approved, but no handler is installed to apply it.`);\n    await deletePendingApproval(approval.approval_id);\n    await notifyApprovalResolved({ approval, session, outcome: 'approve', userId });\n    await wakeContainer(session);\n    return;\n  }\n\n  const payload = JSON.parse(approval.payload);\n  try {\n    await handler({ session, payload, approval, userId, notify });\n    log.info('Approval handled', { approvalId: approval.approval_id, action: approval.action, userId });\n  } catch (err) {\n    log.error('Approval handler threw', { approvalId: approval.approval_id, action: approval.action, err });\n    await notify(\n      `Your ${approval.action} was approved, but applying it failed: ${err instanceof Error ? err.message : String(err)}.`,","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/modules/approvals/response-handler.ts#L90-L126","documentation":"An approval was approved, but no handler is registered for its action string (getApprovalHandler returned null). The pending row is deleted and the requester is notified that the approval cannot be applied.","triggerScenarios":"A pending_approval row exists with an 'action' value whose handler was never registered at startup; a plugin/module that registers the handler failed to load; action renamed between versions leaving stale rows.","commonSituations":"Upgrading NanoClaw where an action was renamed; a skill-installed module that registers approval handlers missing or failed to import; hand-inserted pending rows.","solutions":["Identify the action name from the log and verify the module that registers its handler is installed and imported","Re-request the approval so a fresh row with a supported action is created","Clean stale pending_approvals rows left over from an older version"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!getApprovalHandler(action)) {\n  throw new Error(`No handler for approval action '${action}' — register it before requesting approval`);\n}","typeGuard":"const isRegisteredAction = (a: string): boolean => getApprovalHandler(a) !== null;","tryCatchPattern":null,"preventionTips":["Register all approval handlers in one barrel imported at startup","On upgrade, drain or migrate stale pending_approvals rows"],"tags":["approvals","handler-missing","registry"],"backgroundTag":"handler-not-registered","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}