Skip to content

Wizard-generated synthetic block can never run: teacher_backend/api_base are never emitted, so every --generate-data call fails (CR-A18-012) #411

Open

Description

@cemililik

Wave 1 · theme D1-5: Training, merging and export correctness · highest severity High · 2 finding(s) · effort small

Summary

When synthetic is enabled, buildYaml emits only enabled/teacher_model/seed_file/api_key_env (wizard.js:844-851). teacher_backend therefore defaults to 'api' and api_base to '' (config.py:1333-1343). _call_api_teacher raises 'synthetic.api_base is required for API teacher backend.' for every prompt (synthetic.py:218-222). The config validator does not check api_base, so --dry-run passes. The hints offer 'API model name ... or local model path' for the teacher (translations.js:1803) and say 'Empty = local teacher model' for the key env (translations.js:1808), but the wizard never switches teacher_backend to local, and it rejects an empty key env (wizard.js:461-463).

Primary finding

CR-A18-012 — Wizard-generated synthetic block can never run: teacher_backend/api_base are never emitted, so every --generate-data call fails

severity Medium · reachability default · intent contract-violation · confidence confirmed · independently confirmed · reproduced end to end

What happens. When synthetic is enabled, buildYaml emits only enabled/teacher_model/seed_file/api_key_env (wizard.js:844-851). teacher_backend therefore defaults to 'api' and api_base to '' (config.py:1333-1343). _call_api_teacher raises 'synthetic.api_base is required for API teacher backend.' for every prompt (synthetic.py:218-222). The config validator does not check api_base, so --dry-run passes. The hints offer 'API model name ... or local model path' for the teacher (translations.js:1803) and say 'Empty = local teacher model' for the key env (translations.js:1808), but the wizard never switches teacher_backend to local, and it rejects an empty key env (wizard.js:461-463).

Where.

Evidence.

  • From h/dry with seeds.jsonl: fpy -m forgelm --config ../yamls/synthetic.yaml --generate-data -> 'Generation failed for prompt 0/1: synthetic.api_base is required for API teacher backend.' ... 'produced no usable examples.' EXIT=2. Loading the same YAML with load_config succeeds.

Recommended fix. Expose teacher_backend and api_base (default https://api.openai.com/v1 for the api backend), and emit teacher_backend: local when a local path is chosen.

Other findings with the same root cause

These close with the same fix; update them in the same pull request.

DOC-D4B09-011 — site/js/translations.js: broken example — Teacher/judge 'API model name (gpt-4o, claude-opus-4-7) or local model path'; synthetic api_key_env 'Empty = local teacher model'; judge 'Empty = local judge…

severity High

Where. site/js/translations.js:1801-1808 (wizard.synthetic.enabled.detail/.teacher_model.hint/.api_key_env.hint), :1747-1749 (wizard.judge.model.hint/.api_key_env.hint) · type: broken example

The document says. Teacher/judge 'API model name (gpt-4o, claude-opus-4-7) or local model path'; synthetic api_key_env 'Empty = local teacher model'; judge 'Empty = local judge model'

What the code does. (1) The wizard emits synthetic: enabled, teacher_model, seed_file, api_key_env (site/js/wizard.js:844-850) but no api_base. teacher_backend defaults to 'api' (config.py:1333) and the API teacher raises ValueError 'synthetic.api_base is required' for every prompt (synthetic.py:221-222), which is caught per prompt, so the run produces no data. The config still passes --dry-run. (2) An empty api_key_env does not select a local teacher; local needs teacher_backend: local, which the wizard never emits. The wizard also rejects an empty key (wizard.js:461-462). (3) Judge and teacher API calls speak the OpenAI chat-completions format (judge.py:223-233; synthetic.py:208-246). A claude-* model name is sent to api.openai.com unless judge_api_base or synthetic.api_base points at an OpenAI-compatible gateway, and the wizard exposes neither. (4) The judge hint 'Empty = local judge model' conflicts with wizard.js:441-442, which makes it required.

Code references. site/js/wizard.js:844-850, forgelm/synthetic.py:208-246, forgelm/config.py:1333,1343, forgelm/judge.py:223-233

User impact. The synthetic-data step of the wizard produces a YAML that yields nothing. Users who follow the hint and enter a Claude model name get API errors.

Proposed correction. Write: 'Model name served by an OpenAI-compatible /chat/completions endpoint (set the endpoint in synthetic.api_base / evaluation.llm_judge.judge_api_base). Leave the API-key variable empty only if you set teacher_backend: local in the YAML.' Delete the 'Empty = local' sentences or make them true.

Acceptance criteria

  • A regression test reproduces the failure scenario and asserts the corrected behaviour.
  • Documentation listed above is corrected in English and in its Turkish mirror in the same PR.
  • Every finding in this issue is resolved or explicitly closed with a reason.

Found by the October 2026 ForgeLM code and documentation review against commit cab2947. Code links point at that commit; line numbers may have moved since. Finding IDs (CR-…, DOC-…, TECH-…) are stable references for this backlog.

Activity

  1. added
    bugSomething isn't working
    documentationImprovements or additions to documentation
    severity: highWrong behaviour or a false claim users rely on
    source: review-2026-10Found by the October 2026 code and documentation review
    wave: 1Roadmap wave 1: high severity, small effort
    on Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: siteCode area: sitebugSomething isn't workingdocumentationImprovements or additions to documentationseverity: highWrong behaviour or a false claim users rely onsource: review-2026-10Found by the October 2026 code and documentation reviewwave: 1Roadmap wave 1: high severity, small effort

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions