tinyhumansai/openhuman · error
[skill-latency] tool chain on thread ${event.thread_id} took
Error message
[skill-latency] tool chain on thread ${event.thread_id} took ${latency.elapsedMs}ms across ${latency.toolCount} tool(s) — exceeds the ${SKILL_TOOL_CHAIN_TARGET_MS}ms target What it means
Observability-only log from ChatRuntimeProvider (#4273 AC3): finishChain closed the per-turn tool-chain latency window and the elapsed time from first tool to last tool across toolCount calls exceeded SKILL_TOOL_CHAIN_TARGET_MS (60s). Nothing fails or blocks — the turn completes; the log exists to track skill/tool-chain latency regressions against the target.
Source
Thrown at app/src/providers/ChatRuntimeProvider.tsx:1106
output_tokens: event.total_output_tokens,
});
// Close the tool-chain latency window and surface overruns of the 60s
// target (#4273, AC3). Observability only — never blocks the turn.
const latency = skillLatencyRef.current.finishChain(
segmentDeliveryKey(event.thread_id, event.request_id),
{ ok: true }
);
if (latency) {
rtLog('skill_tool_chain_latency', {
thread: event.thread_id,
request: event.request_id,
elapsed_ms: latency.elapsedMs,
tools: latency.toolCount,
within_target: latency.withinTarget ? 'true' : 'false',
});
if (!latency.withinTarget) {
console.warn(
`[skill-latency] tool chain on thread ${event.thread_id} took ${latency.elapsedMs}ms ` +
`across ${latency.toolCount} tool(s) — exceeds the ${SKILL_TOOL_CHAIN_TARGET_MS}ms target`
);
}
}
// Parallel (forked) turn: resolve only its own lane. The primary turn's
// stream / status / lifecycle / active marker may still be running, so
// we must NOT clear them here. Segmented parallel turns already
// persisted via `onSegment` (keyed by thread+request); a single-bubble
// parallel turn persists its full response now.
if (
event.request_id !== undefined &&
store.getState().chatRuntime.parallelRequestThreads[event.request_id] !== undefined
) {
const parallelRequestId = event.request_id;
dispatch(recordChatTurnUsage(chatTurnUsagePayload(event)));
if (!event.segment_total && event.full_response.length > 0) {View on GitHub (pinned to 7491200858)
Solutions
- Inspect which tools dominated the chain (pair with per-tool timing events on the same thread/request)
- Treat as a performance signal: long-running tools (shell, generation) or retry loops are usual culprits
- File/tune the specific slow tool rather than acting on the aggregate alone
Defensive patterns
Strategy: fallback
When it happens
Trigger: Thrown at app/src/providers/ChatRuntimeProvider.tsx:1106 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17).
Data as JSON: /api/errors/5fba99241a5f589a.
Report an issue: GitHub.