Match log lines and errors with their fixes, and separate command, worker, connection and request problems
Start with what the bot printed. The client logs startup, readiness, lost connections, rate-limit waits, shutdown and every application error by default. Each readable log line shows its record code in brackets after the category, such as [lifecycle.connectionLost]. Then check the operation's Result or native Effect error. The describeError(error) function prints any SDK error with its code, suggested fix and cause chain
The error and log codes page lists every code with its meaning and fix. The table below covers the most common ones
The token was missing or empty, or it started with Bot or Bearer
What to do
The environment variable holding the token is probably unset. Start the bot with node --env-file=.env bot.js from the folder that holds .env, or set the variable in the shell, and pass only the token without a scheme. Surrounding spaces and one pair of quotes are removed. In a project made by fluxerly init, set FLUXER_BOT_TOKEN in the .env file that init wrote
Check that the configured value is the whole bot token, or regenerate the token in the application settings and update the configuration. The SDK does not retry a rejected token
Fluxer closed a shard with 4011 under sharding: "auto" or without sharding settings, so the SDK counted the communities again and moved every shard to a larger plan. Events sent during the move were missed
What to do
Nothing, unless it repeats. Without sharding settings, set sharding: "auto" so the next start opens enough shards at once. After 3 moves within an hour, the next 4011 ends the client with lifecycle.connectionEnded
A child's shard was closed with 4011 under the supervisor's totalShards: "auto". At Warn, the supervisor stopped every child, counted again and started a larger plan. At Error, it had already moved 3 times within an hour or reached 16,384 shards, so it shut down
What to do
At Error, check why the community count keeps growing, or choose a larger numeric totalShards
Shards resumed sessions from the session store, which carry no community data, so the SDK refilled the enabled community, role and channelcaches through REST. At Warn, some communities failed or the refill stopped early, such as when the community list repeated a page
What to do
At Warn, read the message and any error. The missing cache entries fill as events and requests arrive
A shutdown with drainMs stopped accepting new events and waited for running handlers, their waiting events, running scheduled tasks and REST requests. A lifecycle.drained record means all of it finished in time
A subscription stopped with events still waiting in its queue, so they never reached it. At Info the client was closing, and at Debug the subscription itself closed. The count is in fields.discarded, and diagnostics().counters.eventsDropped.closed includes it
A draining shutdown received events that open subscriptions or collectors would have received and did not deliver them, because it accepts no new events. The count is in fields.refused, and diagnostics().counters.eventsDropped.closed includes it
A request failed with reason busy because the REST queue or the upload byte budget was full. It is logged at most once a minute, and every such failure is counted in diagnostics().counters.restBusy
What to do
Send fewer requests at once, or raise the limit the message names
The SDK logs HTTP 401 or 403 rejections at Warn even when the application handles the Result, because they usually indicate a lasting token or permission problem. It holds the Warn for up to one second, replacing it with the handler or command's failure record only if that callback fails with the same rejection while it is held and no onError hook is configured for that failure. Identical repeats collapse into one record per minute by default
What to do
Follow the record's hint. A bot that expects these rejections can set the rest category to error, as logging shows
An eventhandler threw, rejected or returned an Err
What to do
Fix the error shown with its stack. The handler keeps receiving later events. When an onError hook exists but did not receive the report, fields.reportOutcome says why: queueFull, interrupted, clientClosed or subscriptionClosed
A handler, subscription or command router was registered after shutdown began, often from a handler still running at the time. It received an already-closed handle and never runs
What to do
Nothing during shutdown. At other times, register everything before stopping the client
A command guard, cooldown or argument rejected a message, or no command matched
What to do
With runBot, argument errors, active cooldowns and guards with a deny reason get a reply unless onReject is "silent". A guard returning false sends nothing, even with the reply default. Add onReject to a router from commands.create, and onUnmatched where users need feedback for unknown commands, a group without a subcommand or a syntax mistake such as an unclosed quote
Report it with the output of describeError. Code application.defect instead points at application code: The callback named in its cause, or a property getter on passed options or input that threw the cause
Run with FLUXERLY_DEBUG=1 to add Debug records for every area, or FLUXERLY_DEBUG=rest,ratelimit for selected ones. See logging
What Happens to Collectors Registered After Shutdown Began
Node.js could not open the file named after --env-file. Run the command from the bot's folder, and check that the file is named exactly .env. Some editors, such as Notepad, save it as .env.txt. Show file extensions in the file manager to spot that
The Process Fails with a Node.js Version Error
Error: Fluxerly needs Node.js 24.15 or newer, but this is Node.js 22.12.0. Install a current Node.js release from https://nodejs.org, then run the bot again
The SDK checks the Node.js version when it loads. Run node --version to see the version in use, install a newer release, and open a new terminal so that it is found first
The Process Fails with a Require Error
Error: Fluxerly is ESM-only. Use import, and set "type": "module" in package.json (or use .mjs files)
The SDK ships only ECMAScript modules. Replace require("@neontechspace/fluxerly") with import, and either add "type": "module" to the project's package.json or name the file with .mjs
TypeScript Cannot Find AbortSignal or AsyncDisposable
Install the Node.js types as a development dependency and include them, for example with "types": ["node"] in tsconfig.json. Handler signals are AbortSignal values and clients support await using, so the SDK's declarations use those Node.js types
The bot is running, and the message is from a person, not a bot. The starter answers the !ping command, with command names matched without regard to letter case
The bot can view the channel and send messages there
A command router uses the expected prefix, and the attached router is the one returned by the last register or registerMany call. Each call returns a new router, so attaching an earlier one misses later commands
No guard, cooldown or argument rejected the command. Rejected and unmatched commands are logged at Debug and counted in diagnostics().counters. With runBot, argument errors, active cooldowns and guards with a deny reason get an explanation unless onReject is "silent". A guard returning false intentionally sends nothing. A router from commands.create sends these explanations only with onReject: "reply", and onUnmatched answers unknown commands, a group typed without a subcommand and a syntax mistake such as an unclosed quote
The reply did not fail. The starter returns its reply, so a failed reply is logged as commands.failed with a message that tells local validation, provider rejection, timeout and delivery uncertainty apart
A callback that returns an Err result fails like one that throws, so its error reaches onError or the log. Handle an expected failure inside the callback when it should not count as a failure. See commands and failure handling
Webhook token: Check the webhookID and token, or recreate the webhook and use its new token
OAuth client: Check the configured OAuth client ID and client secret
User access token: Refresh it, or ask the user to authorize the application again
A Moderation Action Fails with HTTP 400
Suppose a kick, ban, timeout, role change or deletion of another person's message fails with HTTP 400 and errors.apiCode(error) returns "twoFactorRequired", although the bot holds the permission. The community requires two-factor authentication for moderation, and the account that owns the bot's application does not have it enabled. The community's mfaLevel is GuildMfaLevels.Elevated in such a community
Enable two-factor authentication on the account that owns the bot's application, then try again. Retrying without that change fails the same way. See communities that require two-factor authentication
A client.onsubscription registered with overflow: "stop" closes when its queue is full, while the gateway stays connected. Observe its waitForClose() outcome. The SDK runner watches its eventsubscriptions, its command router and the client connection. The diagnostics().events counters show registrations and running callbacks, but cannot tell whether a particular application task is working
The diagnostics().rest.queuedRequests and activeRequests values show local queueing for this client. An operation deadline includes the wait in that queue and required SDK cleanup. A timeout after the request was sent does not prove that the write failed on Fluxer, so it is an uncertain write. Do not replay it blindly
The Connection Is Recovering
Each lifecycle.connectionLost record names the reason and the next step, including the close code and its meaning when one is available. Transient recovery differs from terminal authentication or protocol rejection, which ends with lifecycle.connectionEnded and the error shown in full. The retained run() or waitForClose() outcome supplies the terminal result
Do not create another client or repeat connect() merely because the existing client is recovering. The client already owns that recovery lifetime. A closed client requires a new explicitly owned instance
Shutdown Is Waiting, or Application Work Finishes Afterward
Check which work is still running. SDK shutdown waits for its own resources to close. It also waits for collector progress callbacks and native scoped finalizers, so one of those that never finishes can hold up shutdown. The lifecycle.shutdownComplete record reports how long cleanup took, and each failed cleanup step is logged as lifecycle.cleanupFailed
Avoid process.exit() as a cleanup shortcut. Set process.exitCode after application cleanup instead. Neither cancellation nor a timeout proves rollback of an external mutation
Keep Diagnostics Safe and Useful
Record the SDK version from the lifecycle.starting record, the Node version, the record codes and the output of describeError. The SDK masks tokens, Authorization headers, client secrets, invite codes and the user name and password in URLs in every record
Leave unsafe payload logging off when sharing logs. Application error messages and stacks still appear in ordinary logs, so redact message content from those errors too