{"record":{"id":"98f5c7ac1dc98ee6","repo":"can1357/oh-my-pi","slug":"missing-map-observation-for-files-index-filena","errorCode":null,"errorMessage":"Missing map observation for ${files[index]?.filename ?? \"unknown\"}","messagePattern":"Missing map observation for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/commit/conventional/map-reduce.ts","lineNumber":135,"sourceCode":"\t\t};\n\t}\n\tconst results = await mapWithConcurrency(batches, MAP_PHASE_CONCURRENCY, async (batch, batchIndex) => {\n\t\tconst batchFiles = batch.map(index => files[index]).filter(value => value !== undefined);\n\t\tconst mapped = await mapFileBatch(\n\t\t\tbatchFiles,\n\t\t\theaders.headerForFiles(batchFiles.map(file => file.filename)),\n\t\t\tinference,\n\t\t\t`Mapping batch ${batchIndex + 1}/${batches.length} (${batchFiles.length} files)…`,\n\t\t\tbudget,\n\t\t);\n\t\treturn batch.map((fileIndex, index) => ({ fileIndex, observation: mapped[index] }));\n\t});\n\tfor (const batch of results) {\n\t\tfor (const item of batch) if (item.observation) observations[item.fileIndex] = item.observation;\n\t}\n\treturn observations.map((observation, index) => {\n\t\tif (observation) return observation;\n\t\tthrow new Error(`Missing map observation for ${files[index]?.filename ?? \"unknown\"}`);\n\t});\n}\n\nasync function mapFileBatch(\n\tfiles: readonly ConventionalFileDiff[],\n\tcontextHeader: string,\n\tinference: CommitInference,\n\tprogressLabel: string,\n\tbudget: number,\n): Promise<ConventionalFileObservation[]> {\n\tconst promptFiles = files.map(file => ({ path: file.filename, diff: renderFileDiffForBatch(file, budget) }));\n\tconst prompts = renderConventionalPrompt(\"map\", { files: promptFiles, context_header: contextHeader });\n\treturn inference.complete(\n\t\t{\n\t\t\toperation: \"map-reduce/map\",\n\t\t\trole: \"map\",\n\t\t\tpromptFamily: \"map\",\n\t\t\tsystemPrompt: prompts.system,","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/commit/conventional/map-reduce.ts#L117-L153","documentation":"After the parallel map phase completes, observations are collected per file index. If an LLM result arrives without an observation (model produced no usable per-file summary), the final mapping step throws rather than silently returning a sparse array. Raised by mapPhase.","triggerScenarios":"Calling mapPhase (or its callers like observations) when one or more per-file batch LLM calls returned a result whose observation field is empty/undefined — e.g. empty model output, parse failure in the map prompt contract, or a batch item dropped due to an abort/skip.","commonSituations":"Large batches where the model hits token limits and omits some file summaries, provider returning empty content for some calls, malformed map output that fails lenient extraction, or an aborted signal causing partial results.","solutions":["Retry the map phase; partial LLM failures are usually transient","Reduce batch size (files per LLM call) so the model reliably summarizes each file","Use a stronger/larger model for the map phase","Inspect the map prompt/output extraction for contract mismatches after model changes"],"exampleFix":"// before: one missing observation aborts everything\nconst observations = await mapPhase(files, inference, config);\n// after: retry once on failure\nlet observations;\ntry {\n  observations = await mapPhase(files, inference, config);\n} catch {\n  observations = await mapPhase(files, inference, config);\n}","handlingStrategy":"retry","validationCode":"const batches = await collectMapResults();\nconst missing = batches.filter((b) => !b.observation);\nif (missing.length > 0) { /* re-run map for missing indices */ }","typeGuard":null,"tryCatchPattern":"try {\n  observations = await mapPhase(files, inference, config);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith(\"Missing map observation\")) {\n    observations = await mapPhase(files, inference, config); // retry\n  } else throw err;\n}","preventionTips":["Keep per-batch file counts small enough for the model's output budget","Use a model that reliably completes the per-file summary format","Treat partial LLM results as retryable, not fatal"],"tags":["map-reduce","llm","missing-result"],"backgroundTag":"missing-llm-output","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}