Skip to main content

Diagnostics channels

Arcscord publishes opt-in manager lifecycle messages through Node.js node:diagnostics_channel. Channels are dormant until subscribed: when no listener is present, Arcscord does not construct the message, timestamps, metadata, or collection copies.

The API covers command, component, and event managers. LocaleManager does not publish diagnostics channels.

On this page​

Getting started​

managerDiagnosticChannels provides typed, process-wide channel instances:

import { managerDiagnosticChannels } from "arcscord";

const onExecution: Parameters<
typeof managerDiagnosticChannels.command.execute.subscribe
>[0] = (message) => {
if (message.phase === "end") {
console.log(message.execution.interaction.id, message.durationMs);
}
};

managerDiagnosticChannels.command.execute.subscribe(onExecution);

// Remove the same function reference when instrumentation is stopped.
managerDiagnosticChannels.command.execute.unsubscribe(onExecution);

The exported object is typed as ManagerDiagnosticChannels. Each listener narrows its message through the phase discriminant.

Using Node.js directly​

Channel identity is global by name within a process. Importing Arcscord's registry is optional at runtime:

import { channel } from "node:diagnostics_channel";

const commandExecute = channel("arcscord:manager:command:execute");

commandExecute.subscribe((message) => {
if (message.phase === "end") {
console.log(message.durationMs);
}
});

This returns the same channel instance as managerDiagnosticChannels.command.execute. In plain JavaScript, no Arcscord type import is necessary. In TypeScript, Node.js types message as unknown; use Arcscord's channel registry or import the channel's message type when static typing is needed.

Keep acquired channels at module scope. This follows Node.js's recommendation to reuse channel objects and ensures the reference remains alive on Bun.

Message conventions​

Every message contains these fields:

FieldTypeDescription
phase"start" | "end" | "error"Lifecycle phase. A channel may support only a subset.
managerCommandManager | ComponentManager | EventManagerManager that published the message.
clientArcClientClient that owns the manager.
timestampnumberUnix timestamp in milliseconds when this message was published.

Lifecycle phases add the following fields consistently:

PhaseAdditional fields
startoperationId: DiagnosticOperationId, startedAt: number
endoperationId: DiagnosticOperationId, startedAt: number, endedAt: number, durationMs: number
erroroperationId: DiagnosticOperationId, error: unknown or a narrower channel-specific error type

DiagnosticOperationId is an opaque, process-local symbol. Every phase produced for one operation contains the same identifier. It is intended as a Map or Set key and is not JSON-serializable.

One-shot registry channels publish only end; they therefore have no startedAt, endedAt, or durationMs. The tables below list only fields that are specific to that channel and phase.

Command channels​

arcscord:manager:command:load​

  • Export: managerDiagnosticChannels.command.load
  • Message type: CommandLoadDiagnosticMessage
  • Published by: CommandManager.loadCommands()
  • Use for: command validation and generated Discord API bodies
PhaseChannel-specific fieldsMeaning
startcommands: readonly Command[], group: stringTransformation and validation are starting.
endcommands: readonly Command[], group: string, apiCommands: readonly RESTPostAPIApplicationCommandsJSONBody[]All definitions were transformed successfully.
errorcommands: readonly Command[], group: string, error: ArcscordErrorA definition, middleware, or autocomplete declaration was invalid.

arcscord:manager:command:register​

  • Export: managerDiagnosticChannels.command.register
  • Message type: CommandRegisterDiagnosticMessage
  • Published by: pushGlobalCommands() and pushGuildCommands()
  • Use for: Discord REST latency and deployment synchronization
PhaseChannel-specific fieldsMeaning
startcommands: readonly RESTPostAPIApplicationCommandsJSONBody[], scope: "global" | "guild", guildId?: string, config: CommandRegistrationScopeConfigSynchronization is starting with the resolved scope configuration.
endStart fields plus registrations: readonly ApplicationCommandRegistration[]Discord returned the registrations available after synchronization.
errorStart fields plus error: ArcscordErrorThe application was unavailable or a REST synchronization step failed.

arcscord:manager:command:resolve​

  • Export: managerDiagnosticChannels.command.resolve
  • Message type: CommandResolveDiagnosticMessage
  • Published by: CommandManager.resolveCommand()
  • Use for: explaining why a built command is or is not dispatchable
PhaseChannel-specific fieldsMeaning
endcommand: Command, registration?: ApplicationCommandRegistration, resolvedName?: stringResolution was attempted. Optional fields are absent when no Discord registration matched.

arcscord:manager:command:dispatch​

  • Export: managerDiagnosticChannels.command.dispatch
  • Message type: CommandDispatchDiagnosticMessage
  • Published by: the complete command-interaction dispatcher
  • Use for: end-to-end latency and failures before run()
PhaseChannel-specific fieldsMeaning
startinteraction: CommandInteractionArcscord received a command interaction.
endinteraction: CommandInteraction, outcome: CommandExecutionOutcomeThe execution pipeline produced a terminal outcome.
errorinteraction: CommandInteraction, stage: CommandDispatchStage, locale?: string, error: unknownDispatch stopped during resolve, options, context, defer, or execution.

arcscord:manager:command:execute​

  • Export: managerDiagnosticChannels.command.execute
  • Message type: CommandExecuteDiagnosticMessage
  • Published around: execution interceptors, middleware, and command run()
  • Use for: command duration and normalized success/failure metrics
PhaseChannel-specific fieldsMeaning
startexecution: CommandExecutionContextThe execution-interceptor chain is starting.
endexecution: CommandExecutionContext, outcome: CommandExecutionOutcomeThe chain completed, including handler failures, defects, or middleware cancellation.
errorexecution: CommandExecutionContext, error: unknownThe interceptor chain itself failed to produce an outcome.

arcscord:manager:command:autocomplete​

  • Export: managerDiagnosticChannels.command.autocomplete
  • Message type: CommandAutocompleteDiagnosticMessage
  • Published by: the autocomplete dispatcher
  • Use for: autocomplete resolution, latency, and failures
PhaseChannel-specific fieldsMeaning
startinteraction: AutocompleteInteractionArcscord received an autocomplete interaction.
endinteraction: AutocompleteInteraction, command: CommandExecutionContext["command"], focused: { name: string; value: string | number }, locale: stringThe matching autocomplete handler completed successfully.
errorinteraction: AutocompleteInteraction, error: unknown, command?, focused?, locale?Lookup or execution failed. Optional fields are present only if that step had resolved them.

Component channels​

arcscord:manager:component:load​

  • Export: managerDiagnosticChannels.component.load
  • Message type: ComponentLoadDiagnosticMessage
  • Published by: each loadComponent() call, including calls from loadComponents()
  • Use for: route and middleware validation
PhaseChannel-specific fieldsMeaning
startcomponents: readonly ComponentHandler[]Validation is starting for the contained handler.
endcomponents: readonly ComponentHandler[], loaded: numberThe handler was added to the registry.
errorcomponents: readonly ComponentHandler[], error: ArcscordErrorRoute parsing, duplicate detection, or middleware validation failed.

arcscord:manager:component:unload​

  • Export: managerDiagnosticChannels.component.unload
  • Message type: ComponentUnloadDiagnosticMessage
  • Published by: ComponentManager.unloadComponent()
  • Use for: registry cleanup auditing

The identity-based cleanup used by ArcClient.loadHandlers() when rolling back a failed batch does not publish this route-unload channel.

PhaseChannel-specific fieldsMeaning
endroute: string, component?: ComponentHandler, removed: booleanThe unload attempt completed. component is present only when a handler was removed.

arcscord:manager:component:dispatch​

  • Export: managerDiagnosticChannels.component.dispatch
  • Message type: ComponentDispatchDiagnosticMessage
  • Published by: the complete component-interaction dispatcher
  • Use for: route matching, context creation, and end-to-end latency
PhaseChannel-specific fieldsMeaning
startinteraction: MessageComponentInteraction | ModalSubmitInteractionArcscord received a component interaction.
endinteraction, outcome: ComponentExecutionOutcomeThe execution pipeline produced a terminal outcome.
errorinteraction, stage: ComponentDispatchStage, locale?: string, error: unknownDispatch stopped during match, values, context, defer, or execution.

arcscord:manager:component:execute​

  • Export: managerDiagnosticChannels.component.execute
  • Message type: ComponentExecuteDiagnosticMessage
  • Published around: execution interceptors, middleware, and component run()
  • Use for: component duration and normalized outcomes
PhaseChannel-specific fieldsMeaning
startexecution: ComponentExecutionContextThe execution-interceptor chain is starting.
endexecution: ComponentExecutionContext, outcome: ComponentExecutionOutcomeThe chain completed, including handler failures, defects, or middleware cancellation.
errorexecution: ComponentExecutionContext, error: unknownThe interceptor chain itself failed to produce an outcome.

Event channels​

arcscord:manager:event:load​

  • Export: managerDiagnosticChannels.event.load
  • Message type: EventLoadDiagnosticMessage
  • Published by: each loadEvent() call, including calls from loadEvents()
  • Use for: duplicate handlers and intent validation
PhaseChannel-specific fieldsMeaning
startevents: readonly AnyLoadableEventHandler[]Validation is starting for the contained handler.
endevents: readonly AnyLoadableEventHandler[], loaded: numberThe handler was added to its source registry.
errorevents: readonly AnyLoadableEventHandler[], error: ArcscordErrorA duplicate or configured intent-check failure prevented loading.

arcscord:manager:event:unload​

  • Export: managerDiagnosticChannels.event.unload
  • Message type: EventUnloadDiagnosticMessage
  • Published by: EventManager.unloadEvent()
  • Use for: Gateway and custom-source registry cleanup
PhaseChannel-specific fieldsMeaning
endsource: EventSource, name: string, event?: AnyLoadableEventHandler, removed: booleanThe unload attempt completed. event is present only when a handler was removed.

arcscord:manager:event:dispatch​

  • Export: managerDiagnosticChannels.event.dispatch
  • Message type: EventDispatchDiagnosticMessage
  • Published around: delivery to each matched Gateway or custom-source handler
  • Use for: delivery latency and pre-ready outcomes
PhaseChannel-specific fieldsMeaning
startsource: EventSource, event: AnyLoadableEventHandler, args: readonly unknown[]Delivery to one handler is starting.
endStart fields plus outcome: EventExecutionOutcomeDelivery ended. The outcome may be cancelled by beforeReady: "drop" or contain a readiness defect.

arcscord:manager:event:execute​

  • Export: managerDiagnosticChannels.event.execute
  • Message type: EventExecuteDiagnosticMessage
  • Published around: Gateway or custom-source execution interceptors and run()
  • Use for: handler duration and normalized outcomes
PhaseChannel-specific fieldsMeaning
startexecution: AnyEventExecutionContext | AnySourceEventExecutionContextThe appropriate execution-interceptor chain is starting.
endexecution, outcome: EventExecutionOutcomeThe chain completed, including handler success, failure, or defect.
errorexecution, error: unknownThe interceptor chain itself failed to produce an outcome.

arcscord:manager:event:intent​

  • Export: managerDiagnosticChannels.event.intent
  • Message type: EventIntentDiagnosticMessage
  • Published when: Gateway intent analysis finds missing or partial coverage
  • Use for: startup configuration diagnostics
PhaseChannel-specific fieldsMeaning
endissue: EventIntentCheckIssue, action: "off" | "warn" | "error"An issue was found and the manager resolved the configured action. Custom sources and intentCheck: false do not publish here.

Correlation and subscription timing​

Execution contexts, interactions, handlers, and event sources are live object references. Use their identity or stable Discord IDs to correlate messages. ExecutionOutcome values are discriminated by kind (completed or cancelled); completed outcomes expose an exit discriminated by status (success, failure, or defect).

Arcscord starts diagnostic work only when the channel has a subscriber. It checks hasSubscribers again before constructing a terminal message, so no terminal payload or diagnostic timestamp is calculated when the channel has become empty.

Subscriptions otherwise follow the native Node.js semantics: publish() calls the subscribers present at publication time. A subscriber installed midway can therefore receive an end or error without its corresponding start, for example when it replaces another subscriber synchronously. Track operationIds received during start and ignore unknown terminal identifiers when complete lifecycle pairs are required.

Subscriber safety​

Subscribers run synchronously in the publisher's execution context. Keep them small and send expensive work to a queue or telemetry SDK. Arcscord does not catch subscriber exceptions; Node.js reports them through its native uncaughtException behavior.

Payloads expose live Arcscord and Discord.js objects and may include user content or identifiers. Do not mutate them or serialize entire payloads blindly. Select explicit fields before exporting telemetry. Arcscord never adds the client token to a diagnostic message.

Complete example​

This example records command latency and outcomes without changing manager configuration:

import type { DiagnosticOperationId } from "arcscord";
import { managerDiagnosticChannels } from "arcscord";

const activeCommands = new Set<DiagnosticOperationId>();

managerDiagnosticChannels.command.execute.subscribe((message) => {
if (message.phase === "start") {
activeCommands.add(message.operationId);
return;
}

// A subscriber installed during an operation may see only its terminal phase.
if (!activeCommands.delete(message.operationId) || message.phase !== "end") {
return;
}

const status = message.outcome.kind === "completed"
? message.outcome.exit.status
: "cancelled";

metrics.histogram("arcscord.command.duration", message.durationMs, {
command: message.execution.interaction.commandName,
status,
});
});

managerDiagnosticChannels.command.dispatch.subscribe((message) => {
if (message.phase === "error") {
metrics.increment("arcscord.command.dispatch_error", {
stage: message.stage,
});
}
});

The runnable starter-bot contains command, component, and intent-channel subscribers.