{"record":{"id":"65797c2107bad957","repo":"can1357/oh-my-pi","slug":"unexpected-stop-no-tiny-smol-model-available-for","errorCode":null,"errorMessage":"unexpected-stop: no tiny/smol model available for classification","messagePattern":"unexpected-stop: no tiny/smol model available for classification","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/session/unexpected-stop-classifier.ts","lineNumber":91,"sourceCode":"\t\t}\n\t\tif (isTinyMemoryLocalModelKey(backend)) {\n\t\t\treturn await classifyLocal(text, backend, deps);\n\t\t}\n\t\treturn undefined;\n\t} catch (error) {\n\t\tlogger.debug(\"unexpected-stop: classification failed\", {\n\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\tbackend,\n\t\t});\n\t\treturn undefined;\n\t}\n}\n\nasync function classifyOnline(text: string, deps: ClassifyUnexpectedStopDeps): Promise<boolean | undefined> {\n\tconst resolved = resolveRoleSelection([\"tiny\", \"smol\"], deps.settings, deps.registry.getAvailable());\n\tconst model = resolved?.model;\n\tif (!model) {\n\t\tthrow new Error(\"unexpected-stop: no tiny/smol model available for classification\");\n\t}\n\tconst apiKey = await deps.registry.getApiKey(model, deps.sessionId);\n\tif (!apiKey) {\n\t\tthrow new Error(`unexpected-stop: no API key for ${model.provider}/${model.id}`);\n\t}\n\tconst metadata = deps.metadataResolver?.(model.provider);\n\tconst maxTokens = ONLINE_REASONING_SAFE_MAX_TOKENS;\n\n\tconst response = await retryTransientCompletion(\n\t\t() =>\n\t\t\tcompleteSimple(\n\t\t\t\tmodel,\n\t\t\t\t{\n\t\t\t\t\tsystemPrompt: [CLASSIFIER_SYSTEM_PROMPT],\n\t\t\t\t\tmessages: [{ role: \"user\", content: text, timestamp: Date.now() }],\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tapiKey: deps.registry.resolver(model, deps.sessionId),","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/session/unexpected-stop-classifier.ts#L73-L109","documentation":"classifyOnline classifies an unexpected stop by asking a small (tiny/smol) model. It resolves the 'tiny' then 'smol' role from settings and the available model list; if neither role resolves to a model it throws this error instead of silently skipping classification.","triggerScenarios":"classifyUnexpectedStop routes to online classification but neither a tiny nor smol model is present in registry.getAvailable() nor resolvable from settings (e.g. no provider with a small model available).","commonSituations":"Fresh install with no API providers configured; all providers disabled so the available model list is empty; custom settings removed the tiny/smol role assignments; offline environment where only local models exist but none are registered.","solutions":["Configure an API key/provider so at least one small model is available in the registry.","Set the tiny or smol role explicitly in settings to an available model.","Handle the error upstream in classifyUnexpectedStop and fall back to local/heuristic classification.","Update the model catalog/registry so small models are discoverable."],"exampleFix":"// before\n// settings has no tiny/smol role and no providers configured -> throws\n// after\nawait settings.set(\"small_model\", \"anthropic/claude-3-5-haiku\"); // provides a tiny/smol candidate","handlingStrategy":"fallback","validationCode":"const resolved = resolveRoleSelection([\"tiny\", \"smol\"], settings, registry.getAvailable());\nconst canClassifyOnline = resolved?.model != null;\n","typeGuard":"function hasSmallModel(r: { model?: unknown }): r is { model: NonNullable<unknown> } {\n  return r != null && \"model\" in r && r.model != null;\n}","tryCatchPattern":"try {\n  verdict = await classifyUnexpectedStop(text, deps);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"no tiny/smol model available\")) {\n    verdict = undefined; // skip classification; rely on local heuristic\n  } else throw err;\n}","preventionTips":["Ensure at least one provider with a small model is configured before enabling online classification.","Explicitly set the tiny/smol role in settings to a stable, cheap model.","Fall back to the local classifier when no small model resolves.","Validate model availability at startup rather than at classification time."],"tags":["classification","model-availability","configuration"],"backgroundTag":"no-model-available","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}