一键导入
yaebal-debug
Use when a yaebal bot fails to compile, start, or respond — install-order type errors, ESM specifier errors, Telegram 400/409/429 responses.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use when a yaebal bot fails to compile, start, or respond — install-order type errors, ESM specifier errors, Telegram 400/409/429 responses.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use when building multi-step dialogs in a yaebal bot — choosing between scenes, conversation, and prompt, and wiring their persistence.
Use when writing or modifying a Telegram bot built on the yaebal framework — bot setup, handlers, filter queries, commands, and context typing.
Use when adding LLM features to a yaebal bot with @yaebal/ai — ctx.ai streaming replies, model adapters, conversation memory, and rate limits.
Use when writing a custom yaebal plugin — the Plugin<In, Out> contract, derive vs decorate, and typed plugin dependencies.
Use when running a yaebal bot in production — long polling with @yaebal/runner vs webhooks with @yaebal/web, graceful shutdown, and error handling.
Use when adding inline/reply keyboards or handling button presses in a yaebal bot — @yaebal/keyboard builders and @yaebal/callback-data typed payloads.
| name | yaebal-debug |
| description | Use when a yaebal bot fails to compile, start, or respond — install-order type errors, ESM specifier errors, Telegram 400/409/429 responses. |
plugin dependencies are typed via Plugin<In, Out> — installing a plugin before what it
requires is a compile error, not a runtime surprise. fix the order, and keep the chain:
bot.install(auth()); // ❌ auth needs ctx.session
bot.install(session({ initial })).install(auth()); // ✅ dependency first
the same error appears when the augmented composer was discarded — derive/decorate/
install return the enriched type; assign or chain the result, don't call them as
fire-and-forget statements on separate lines.
yaebal projects are ESM ("type": "module", moduleResolution: NodeNext). every relative
import needs an explicit .js extension — even from .ts source:
import { db } from "./db"; // ❌ TS2835 / ERR_MODULE_NOT_FOUND at runtime
import { db } from "./db.js"; // ✅
hand-written parse_mode: "MarkdownV2" strings 400 on any unescaped . - ! ( ) etc. don't
escape by hand — send entities instead via @yaebal/fmt (re-exported from "yaebal"):
import { html, md } from "yaebal";
await ctx.send(html`<b>hello</b>, ${ctx.from?.first_name}!`); // interpolation auto-escaped
await ctx.send(md`**bold** and _italic_ — no parse_mode, no escaping`);
two consumers are fighting over one token: a second polling instance (dev shell + deployed
bot), or polling while a webhook is registered. stop the other instance, or clear the
webhook: deleteWebhook(bot, { dropPendingUpdates: true }) from @yaebal/web. one token,
one transport, one process.
telegram returns retry_after in the error's parameters. errors are TelegramError from
@yaebal/core with .code and .parameters. fixes, outermost first:
import { autoRetry } from "@yaebal/again";
import { throttle } from "@yaebal/throttle";
autoRetry(bot.api, { maxRetries: 5 }); // await retry_after, re-run the call
bot.install(throttle({ globalPerSec: 30 })); // don't hit the limit in the first place
for mass sends, use @yaebal/broadcast (built-in pacing) instead of a bare loop.
bot.start()/handleUpdate()? the chain freezes on
first use — register everything before starting.allowedUpdates was set (or a previous setWebhook set
allowed_updates), unlisted update types are silently dropped.getWebhookInfo(bot) from @yaebal/web — pending_update_count and
last_error_message say exactly what telegram sees.on("message:text") doesn't match photos/captions — check the query.ctx.answerCallbackQuery().bot.onError((error, ctx) => …) — log ctx.update alongside the error; the update that
broke the handler is the fastest repro.