Appearance
FAQ 与故障排查
先查错误码速查表,再按症状对号入座。都没命中?在应用设置里确认配置,或联系 你的组织管理员。
错误码速查(开放 API)
| 状态码 | 直接原因 | 自查 |
|---|---|---|
| 400 | 参数校验失败 / authCode 无效、已使用或过期 | 核对参数约束;authCode 只能用一次、5 分钟过期,刷新页面会失效——让页面用 jlt.requestAuthCode() 换新码 |
| 401 | token 缺失/过期;app_key/app_secret 不对;密钥已轮换;应用停用/组织解散 | 401 后丢弃缓存的 token 重新获取再重试一次;确认 secret 是最新(轮换后旧的立即失效) |
| 402 | AI 能力:应用所属组织未开通钱包 | 找发布方组织管理员充值开通(不是安装方) |
| 403 | scope 未授予 / 目标组织未安装 / 知识库未绑定 / 来源 IP 不在白名单 | 看 detail 文案:scope 找对应组织管理员开;IP 则检查后端出口 IP 是否进了白名单 |
| 404 | 组织/团队/应用不存在或不属于目标组织 | 核对 id;团队必须属于 org_id 指定的组织 |
| 429 | 触发限流 | 按退避重试;对照限流表排查是否有循环调用 |
| 502 | 上游模型调用失败 | 稍后重试;持续出现联系平台方 |
| 503 | 通知账号暂不可用(im/send) | 稍后重试 |
免登相关
刷新页面后登录失败(400 authCode 无效) authCode 是一次性的,URL 上那枚在首次登录时已被消费。正确做法见 完整示例:用完即从地址栏清掉, 会话失效时用 jlt.requestAuthCode() 取新码重新登录。
换到的用户身份里 org_role 是什么? 打开应用时所在组织的角色(owner/admin/member)。自建应用恒为应用所属 组织;市场应用为安装方组织。应用要区分"管理员才能审批"就是看这个字段。
能力(scope)相关
明明应用申请了 contacts,为什么 403? 两种情况:① 调用时传了安装方组织的 org_id——市场应用需要安装方管理员 在「权限」里单独授予(安装 ≠ 授权); ② 自建应用则是管理员后来在设置里把勾去掉了。
AI 计费扣谁的组织积分? 恒定扣应用所属(发布方)组织的钱包,跟谁在用、哪个组织安装无关。所以 ai 能力不看安装方授权,只看应用自身申请。
JSAPI 相关
所有调用 15 秒后超时 reject 页面不在机灵兔客户端里打开(普通浏览器直接访问)。先判断再降级:
ts
if (window.jlt) { /* 在客户端里 */ } else { /* 普通网页模式 */ }移动端页面里调 JSAPI 没反应 确认引入的是平台下发的 <script src="…/api/open/jsapi/jlt.js">(v1.2+ 才支持移动容器),并按文档在 jlt.ready 之后再发起调用(见 平台差异)。
localFetch/browserExtract 报"应用未被授予本地能力" 组织管理员在应用设置「开放能力」里勾选本地能力(市场应用还需安装方在 「权限」里授予)。注意本地能力仅桌面端,且每次调用都会弹窗请用户确认 目标地址——用户拒绝也是这个报错路径,别把"没授权"和"用户点了拒绝"混为一谈。
browserExtract 失败提示浏览器/Node 相关错误 无头浏览器依赖桌面端的本地运行时(Node + Playwright)。让用户在客户端 「设置 → 环境检查」一键准备后重试;简单页面优先用 localFetch(无依赖、更快)。
AI Agent 与隔离浏览器会话相关
jlt.agent 报"应用未被授予本地能力/AI 对话能力"agent 需要同时被授予 ai 和 local 两项(安装方需两项都在「权限」 里勾),少一项都会拒绝——跟只需要 local 的 localFetch/browserExtract 不是一回事。
jlt.agent 迟迟没有 resolveagent 不受 15 秒桥超时限制(模型可能要跑多轮工具),需要自己在页面侧加 超时/取消 UI,并在用户想中止时调 jlt.agentStop();不要假设它一定在几秒内 返回。用户拒绝确认弹窗、或本轮达到工具迭代上限(on.truncated 会触发一次) 也会正常收尾,不是卡死。
browserOpen/browserAct/browserRead 返回 { need_consent, url } 而不是内容 会话跳到了一个还没确认过的 origin(比如点了外链、被重定向)。正确处理: 弹一次桌面壳确认框让用户确认该 origin,用户同意后重发同一个调用即可拿到 内容;browserAct 的目标动作已经执行过,同意只是把该 origin 记入会话白名单, 不会重跑一遍动作。未确认 origin 的页面内容不会有任何字节返回给你的应用。
会话报"会话不存在或已过期"/"会话总数已达上限" 隔离浏览器会话有限额:每应用窗口最多 2 个、全局最多 4 个、空闲 10 分钟或 存活超 30 分钟会被自动回收,用完记得 browserClose()(幂等,多调用一次没 副作用)。达到上限就先关掉不用的会话再开新的。
browserAct 报"会话操作次数已达上限,已自动关闭" 单个会话最多 200 次动作(click/type/… 各计一次),到达上限会话直接被关闭 (安全兜底,避免一个会话被无限复用),需要 browserOpen 开一个新会话。
本机文件与分享相关(v1.6.0)
chooseFile/saveFileAs/share 在普通浏览器里点没反应 三者都仅桌面端支持(跟 agent/隔离浏览器会话一样),也都不需要申请 任何 scope(share 除外,见下)——先用 if (window.jlt) 判断是否在机灵兔 客户端里打开,再检查 jlt.getContext().platform === "desktop"。
chooseFile 返回的某个文件只有 error,没有 data_base64 单文件上限 20MB;多选时还有 60MB 的累计上限——排在后面、会让累计超限 的文件即使自身不到 20MB 也会被跳过读取(避免一次选很多大文件把内存打爆)。 需要更大文件时引导用户分批选择。
share 一直没有 resolve,或者选完人却什么都没发生 用户在系统选人组件里点了"取消"——这不是错误,share 会正常 resolve 为 { ok: false };判断 ok 而不是等异常。
share 报"应用未被授予 IM 消息能力"share 虽然是用户自己选人、以自己身份发的消息,但仍然复用 POST /im/send 的同一个 im scope 闸门——组织管理员(市场应用还需安装方)在「开放能力」 里勾选 IM 消息通知 才能用。
jlt.openChat({ group_id }) 打不开群聊 ① 确认 group_id 是真实存在的 IM 群 id(比如某个团队的绑定群,通过 GET /org/teams 拿 im_group_id);② 当前用户必须本来就是这个群的成员—— openChat 只负责导航,不会把人拉进一个他本不属于的群,真实权限由 IM 打开 会话时校验;③ 该变体同样仅桌面端支持。
AI 工具相关
注册工具时"回调地址验证失败" 和事件订阅同一套 challenge 验证:端点要对 {"type":"url_verification","challenge":"…"} 原样回显并返回 200。curl 自测:
bash
curl -s https://your-backend/jlt/tools -H 'Content-Type: application/json' \
-d '{"type":"url_verification","challenge":"abc"}'
# 期待 → {"challenge":"abc"}模型调用工具一直超时 回调等待是工具注册时配的秒数(5–60)——检查你的端点是否同步做了重活(应该 秒回结果,慢逻辑丢队列);工具端点和事件端点可以共用验签代码但路径分开部署 更稳。
数据库查询返回"仅允许 SELECT 查询" 这是设计行为:db 能力永远只读(单条 SELECT/WITH、禁写关键字、行数上限、 语句超时),写操作请走你自己系统的接口。
成员说"AI 不知道我的工具" 工具只在对话请求时按组织解析:确认应用勾了 ai_tools、工具未停用、该 成员属于组织(自建 = 应用组织;市场 = 授予了 ai_tools 的安装方组织)。
事件订阅相关
保存回调地址时验证失败 端点必须对 {"type":"url_verification","challenge":"…"} 原样回显 challenge 并返回 200。用 curl 自测:
bash
curl -s http://localhost:3000/jlt/events \
-H 'Content-Type: application/json' \
-d '{"type":"url_verification","challenge":"abc"}'
# 期待 → {"challenge":"abc"}之前能收到事件,突然收不到了 在应用设置看「待投递 N · 失败 N」:端点最近是否 5xx/超时(防火墙、发布、 改路由)?修好后点**「重投失败事件」**补投。注意验证失败/重试耗尽的旧事件 不会自动补发。
怎么确认事件是真的来自平台? 验签:HmacSHA256(app_secret, "<X-Jlt-Timestamp>.<原始请求体>") 与 X-Jlt-Signature 常量时间比对,并拒绝时间戳过老的请求。完整代码见 事件订阅 §4。
AI 对话组件(mountChat)相关
组件报 HTTP 502 你的后端中继没通或上游报错——看中继日志;Demo 的 /api/chat 直接透传平台 错误体(截断到 300 字符),先确认 JLT_BASE/JLT_APP_KEY/JLT_APP_SECRET 环境变量都对。
组件报 HTTP 402 应用所属组织未开通钱包(ai 能力计费走你的组织钱包)——找组织管理员充值开通。
回复不逐字出现(一次性整段) 后端中继把 SSE 缓冲了(nginx 默认缓冲会攒满才发)。给中继响应加 X-Accel-Buffering: no(Demo 的代码已带),或确认代理链路没有 proxy_buffering on。
刷新后历史丢了 检查持久化接对了没有(存哪里); IndexedDB 在隐私模式/被策略禁用时会静默降级为不存,属预期行为。
本地调试
页面地址/回调地址可以用 http 吗? 仅 http://localhost / http://127.0.0.1 放行(开发调试);正式环境与 上架市场强制 https。注意:回调地址填的是你后端的地址,跟页面地址是两回事。
客户端内嵌的页面怎么调试? DevTools 不方便用,建议:后端逻辑先用 curl/单测验证;页面侧加 console.log 后重新打开应用观察;免登失败时先看 URL(fragment,旧版为 query)上是否带 jlt_auth_code 参数。