{"record":{"id":"92a5cf3d7b650011","repo":"can1357/oh-my-pi","slug":"no-staged-changes-to-analyze","errorCode":null,"errorMessage":"No staged changes to analyze","messagePattern":"No staged changes to analyze","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/commit/conventional/service.ts","lineNumber":75,"sourceCode":"\t\t` ${entries.length} file${entries.length === 1 ? \"\" : \"s\"} changed, ${insertions} insertion${insertions === 1 ? \"\" : \"s\"}(+), ${deletions} deletion${deletions === 1 ? \"\" : \"s\"}(-)`,\n\t);\n\treturn `${lines.join(\"\\n\")}\\n`;\n}\n\n/** Generate a commit message from the staged tree, staging all only when the index is empty. */\nexport async function generateGitCommit(options: GenerateGitCommitOptions): Promise<GeneratedGitCommit> {\n\tconst repo = vcs.requireGit(options.cwd);\n\tconst settings = await Settings.init({ cwd: options.cwd });\n\tconst config = conventionalGenerationConfig(settings.getGroup(\"commit\"));\n\tlet stagedFiles = await repo.changedFiles({ cached: true }, options.signal);\n\tlet stagedAll = false;\n\tif (stagedFiles.length === 0 && options.stageIfEmpty !== false) {\n\t\toptions.onProgress?.(\"Staging all changes…\");\n\t\tawait repo.stageFiles([], options.signal);\n\t\tstagedAll = true;\n\t\tstagedFiles = await repo.changedFiles({ cached: true }, options.signal);\n\t}\n\tif (stagedFiles.length === 0) throw new Error(\"No staged changes to analyze\");\n\n\toptions.onProgress?.(\"Reading staged changes…\");\n\tconst initialDiff = await repo.diffText({ cached: true }, options.signal);\n\tconst diff =\n\t\tBuffer.byteLength(initialDiff) <= config.maxDiffLength\n\t\t\t? initialDiff\n\t\t\t: await repo.diffText({ cached: true, context: 1 }, options.signal);\n\tif (!diff.trim()) throw new Error(\"No staged changes to analyze\");\n\n\tconst numstatEntries = await repo.numstat({ cached: true }, options.signal);\n\tconst stat = renderStat(numstatEntries);\n\tconst numstat = renderNumstat(numstatEntries);\n\tconst context = await collectGenerationContext(options.cwd, options.signal);\n\n\tconst inference = new LazyCommitInference(() => createOmpInference(options, settings, config));\n\ttry {\n\t\tconst result = await generateConventionalCommit({ diff, stat, numstat, config, inference, context });\n\t\treturn { ...result, stagedAll };","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/commit/conventional/service.ts#L57-L93","documentation":"generateGitCommit requires staged changes to analyze. If nothing is staged it first attempts to stage all changes (when options.stageIfEmpty !== false); if the index is still empty after that, it throws because there is no diff to base a commit message on. This is the first of two staged-content checks (this one checks the file list).","triggerScenarios":"Calling generateGitCommit (via generated or runLegacyCommitCommand) in a repo where the index is empty AND staging-all yields nothing — i.e. a clean working tree, or all changes are untracked-but-ignored/unchanged, or stageIfEmpty is disabled with nothing pre-staged.","commonSituations":"Running the commit generator twice (second run: everything already committed), committing in a repo with only untracked files when stageFiles doesn't include untracked paths, or stageIfEmpty:false with a forgotten 'git add'.","solutions":["Stage changes first: git add <files> (or run the generator before committing everything)","Check git status — if the tree is clean there is nothing to commit","Verify ignore rules aren't hiding your changes (.gitignore matching new files)","Don't pass stageIfEmpty:false unless you guarantee a pre-populated index"],"exampleFix":"// before: throws when nothing staged\nconst msg = await generateGitCommit({ cwd, repo });\n// after: pre-check\ndiff --no-index /dev/null /dev/null; git status --porcelain\ngit add -A\nconst msg = await generateGitCommit({ cwd, repo });","handlingStrategy":"validation","validationCode":"const staged = await repo.changedFiles({ cached: true });\nif (staged.length === 0) {\n  await repo.stageFiles([]); // stage all, then re-check\n}","typeGuard":null,"tryCatchPattern":"try {\n  const msg = await generateGitCommit(options);\n} catch (err) {\n  if (err instanceof Error && err.message === \"No staged changes to analyze\") {\n    // inform user: nothing to commit\n  }\n  throw err;\n}","preventionTips":["Check git status --porcelain before running generation","Stage files explicitly instead of relying on stageIfEmpty","Watch for .gitignore hiding untracked work"],"tags":["git","staging","precondition"],"backgroundTag":"nothing-staged","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}