Summary
During spec generation, the LLM occasionally writes .spec.json / .info.json sidecar files without the source file extension (e.g. Preprocessor::preprocess_source.spec.json instead of Preprocessor::preprocess_source.rs.spec.json). Because is_file_ready() expects the full filename including extension ({file_path}.spec.json), the pipeline falsely concludes these functions have no specs, retries 5 times, and then exits with an error. The repeated retries also burn significant API quota and memory.
Reproduction
-
Run FM-Agent on a Rust project:
uv run python main.py /path/to/dsv4-ccc --submodule src/frontend
-
Wait for spec generation on files with :: in the name (e.g. Preprocessor::preprocess_source.rs).
-
Observe that some functions get xxx.spec.json instead of xxx.rs.spec.json.
-
Pipeline retries 5 times, then exits:
[Pipeline] ERROR: Stage 6 Layer 2 failed after 5 attempts.
2 function(s) are still missing valid specs.
Root Cause
The batch prompt tells the LLM:
For each function file `<function-file>`, write TWO JSON files in the SAME directory:
`<function-file>.spec.json`:
For Preprocessor::preprocess_source.rs, the LLM interprets <function-file> as the basename without extension, producing Preprocessor::preprocess_source.spec.json instead of Preprocessor::preprocess_source.rs.spec.json.
This is inconsistent — for some functions the LLM writes the correct name (ExprId::of.rs.spec.json), for others it drops .rs.
Summary
During spec generation, the LLM occasionally writes
.spec.json/.info.jsonsidecar files without the source file extension (e.g.Preprocessor::preprocess_source.spec.jsoninstead ofPreprocessor::preprocess_source.rs.spec.json). Becauseis_file_ready()expects the full filename including extension ({file_path}.spec.json), the pipeline falsely concludes these functions have no specs, retries 5 times, and then exits with an error. The repeated retries also burn significant API quota and memory.Reproduction
Run FM-Agent on a Rust project:
Wait for spec generation on files with
::in the name (e.g.Preprocessor::preprocess_source.rs).Observe that some functions get
xxx.spec.jsoninstead ofxxx.rs.spec.json.Pipeline retries 5 times, then exits:
Root Cause
The batch prompt tells the LLM:
For
Preprocessor::preprocess_source.rs, the LLM interprets<function-file>as the basename without extension, producingPreprocessor::preprocess_source.spec.jsoninstead ofPreprocessor::preprocess_source.rs.spec.json.This is inconsistent — for some functions the LLM writes the correct name (
ExprId::of.rs.spec.json), for others it drops.rs.