{"record":{"id":"85af0483c9ba2b21","repo":"can1357/oh-my-pi","slug":"no-tiny-smol-model-available-for-ai-staging","errorCode":null,"errorMessage":"No tiny/smol model available for AI staging","messagePattern":"No tiny/smol model available for AI staging","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/git-tui/ai-stage.ts","lineNumber":88,"sourceCode":" * stage the matching hunks. Called by the git TUI's unstaged-header wand pill.\n * @throws when no model/key resolves, git fails, or every judgement in a pass errors.\n */\nexport async function aiStage(options: AiStageOptions): Promise<AiStageOutcome> {\n\tconst { cwd, instruction, signal, onProgress } = options;\n\tconst repo = vcs.requireGit(cwd);\n\tconst untracked = options.files.filter(file => file.kind === \"untracked\");\n\tconst tracked = options.files.filter(file => file.kind !== \"untracked\" && file.kind !== \"conflicted\");\n\tif (tracked.length === 0 && untracked.length === 0) throw new Error(\"No unstaged changes to filter\");\n\n\tonProgress?.(\"Resolving model…\");\n\tconst settings = await Settings.init({ cwd });\n\tconst authStorage = await discoverAuthStorage();\n\ttry {\n\t\tconst registry = new ModelRegistry(authStorage);\n\t\tawait registry.refresh();\n\t\tawait loadCliExtensionProviders(registry, settings, cwd);\n\t\tconst model = resolveRoleSelection([\"tiny\", \"smol\"], settings, registry.getAvailable())?.model;\n\t\tif (!model) throw new Error(\"No tiny/smol model available for AI staging\");\n\t\tif (!(await registry.getApiKey(model))) throw new Error(`No API key for ${model.provider}/${model.id}`);\n\t\tconst complete = createCompleter(model, registry.resolver(model), signal);\n\n\t\tconst rawDiff = tracked.length > 0 ? await repo.diffText({ files: tracked.map(file => file.path) }, signal) : \"\";\n\t\tconst fileDiffs = new Map(parseFileDiffs(rawDiff).map(entry => [entry.filename, entry]));\n\n\t\tinterface Candidate {\n\t\t\tfile: Pick<ChangedFile, \"path\" | \"kind\">;\n\t\t\t/** Parsed worktree diff; absent for untracked files. */\n\t\t\tdiff?: FileDiff;\n\t\t}\n\t\tconst candidates: Candidate[] = tracked.flatMap(file => {\n\t\t\tconst diff = fileDiffs.get(file.path);\n\t\t\treturn diff ? [{ file, diff }] : [];\n\t\t});\n\t\tcandidates.push(...untracked.map(file => ({ file })));\n\n\t\t// File pass: one completion sees the whole (batched) list, so files are","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/git-tui/ai-stage.ts#L70-L106","documentation":"aiStage routes its diff-grouping request through a lightweight model; it resolves the configured \"tiny\" or \"smol\" role selection from settings against the registry's available models. If no model fills either role, it throws instead of silently failing later during completion.","triggerScenarios":"Calling aiStage when settings define no tiny/smol role model and no available model in the registry matches the tiny or smol role.","commonSituations":"Fresh installs with default/empty settings, models.json filtered down by provider excludes, or an environment where all candidate models were disabled.","solutions":["Configure a tiny or smol model in settings (role selection) for AI staging.","Ensure a model catalog/provider is configured so the registry has available models.","Check provider exclude/filters in settings that may be hiding eligible models."],"exampleFix":"// before (settings)\n{}\n// after (settings)\n{ \"roles\": { \"smol\": \"anthropic/claude-3-5-haiku\" } }","handlingStrategy":"validation","validationCode":"const settings = await Settings.init({ cwd });\nconst registry = new ModelRegistry(await discoverAuthStorage());\nawait registry.refresh();\nconst hasModel = !!resolveRoleSelection([\"tiny\", \"smol\"], settings, registry.getAvailable())?.model;\nif (!hasModel) { /* fall back to manual staging or configure a model */ }","typeGuard":null,"tryCatchPattern":"try {\n  await aiStage(opts);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"No tiny/smol model available\")) {\n    await manualStage(); // fallback path\n    return;\n  }\n  throw e;\n}","preventionTips":["Configure a tiny/smol role model in settings during setup.","Verify with a settings/registry check before offering AI-staging features in tooling.","Avoid provider exclude filters that eliminate all small models."],"tags":["model-selection","configuration","ai"],"backgroundTag":"missing-model-configuration","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}