[spark-compete] enhance(read): classify HTTP 404 / 401-403 / 429 in read_llm_provider_json#1047
Conversation
…ead_llm_provider_json
spark-cli: classify HTTP 404 / 401-403 / 429 in read_llm_provider_jsonBug
A 404 from a configured provider (most common cause: wrong base URL or wrong model FixInside the existing
The redacted body suffix is preserved on every branch. The generic fallback raise is Before / AfterBefore: After: Verification
Sister precedentspark-telegram-bot PR #603 (merged into our R24 fork branch) added the exact same Dedup check
|
TL;DRsrc/spark_cli/cli.py read_llm_provider_json() (used by openai_compatible_chat_completion and ollama_chat_completion for What changesAdd 404, 401/403, and 429 branches inside the existing urllib.error.HTTPError handler in read_llm_provider_json. Each branch keeps the provider_label and redacted body suffix, but appends a one-line root-cause + one-line recovery command. The fallback raise at the end is preserved for every other status code. No public surface changes outside the SystemExit message text: same function signature, same callers (openai_compatible_chat_completion ollama_chat_completion), same exit code. Files touched: Why this mattersSister-precedent: spark-telegram-bot PR #603 classified the same 4xx fall-through in src/errorExplain.ts by adding a provider_endpoint branch for 404 alongside existing provider_auth (401/403) and provider_rate_limit (429). This change applies the same classification to the spark-cli doctor-LLM path, which is the equivalent operator surface on the CLI side. The diff sits inside the existing try/except, keeps the redacted body suffix, and preserves the generic-fallback raise for any other status code. The redact_sensitive_text wrap is already applied to the body and is not touched. Reproduction (operator-side)
VerificationReview |
Brings registry.json modules.*.commit up to current remote HEAD for the 7 blessed downstream modules. Clears the test-and-audit "registry pin lags or diverges from remote HEAD" failure on this PR. Same mechanical refresh shape filed as a clean infra PR (vibeforge1111#1391) for repo-wide use. Co-Authored-By: ValhallaBuilder <286693580+4gjnbzb4zf-sudo@users.noreply.github.com>
f138fae to
36c3666
Compare
{
"schema": "spark-compete-hotfix-v1",
"event": "spark-compete-first-event",
"submission_mode": "public_repo_pr",
"submission_target_url": "#1047",
"team": {
"name": "SparkThisUp",
"members": [
"ValHallaBuilder",
"Baz707",
"DanFireDash"
],
"github_accounts": [
"4gjnbzb4zf-sudo"
],
"llm_device_holder": "ValHallaBuilder",
"device_holder_github": "4gjnbzb4zf-sudo"
},
"target_repo": {
"id": "vibeforge1111/spark-cli",
"source": "https://github.com/vibeforge1111/spark-cli",
"owner_surface": "operator_cli_doctor_llm_explainer"
},
"issue": {
"type": "usage_friction",
"severity": "low",
"title": "src/spark_cli/cli",
"actual_behavior": "SystemExit('LLM provider returned HTTP 404: Not Found') with no hint that the configured base URL or model name is the most likely cause and no command to verify provider routing.",
"expected_behavior": "404, 401/403, and 429 are categories the operator can act on directly: 404 = wrong base URL or model name ->
spark providers status+spark setup; 401/403 = API key rejected ->spark secrets list+spark setup; 429 = throttle -> retry or switch. Each branch names the root cause and the single recovery command, matching the same shape that landed in spark-telegram-bot src/errorExplain.ts for chat-path 404s.","repro_steps": [
"1. Configure an OpenAI-compatible LLM provider with a base URL whose /chat/completions route does not host the configured model (e.g. point ZAI_BASE_URL at an OpenAI-style host).",
"2. Run
spark doctor llmso the CLI calls openai_compatible_chat_completion.","3. Provider responds HTTP 404 Not Found.",
"4. CLI exits with 'LLM provider returned HTTP 404: Not Found: ' \u2014 no instruction to check the base URL or model."
],
"affected_workflow": "Operator-facing flow in spark-cli."
},
"evidence": {
"safe_links_only": true,
"before_after_proof": "Before: SystemExit('LLM provider returned HTTP 404: Not Found') with no hint that the configured base URL or model name is the most likely cause and no command to verify provider routing.\nAfter: 404, 401/403, and 429 are categories the operator can act on directly: 404 = wrong base URL or model name ->
spark providers status+spark setup; 401/403 = API key rejected ->spark secrets list+spark setup; 429 = throttle -> retry or switch. Each branch names the root cause and the single recovery command, matching the same shape that landed in spark-telegram-bot src/errorExplain.ts for chat-path 404s.","links": [
"https://github.com//pull/1047",
"https://github.com//pull/1047/files"
],
"forbidden": [
"raw secrets",
"raw logs",
"raw conversations",
"private chat IDs",
"session tokens",
"cookies",
"private repo maps",
"raw memory dumps",
"full compile JSON",
"scoring details"
]
},
"proposed_fix": {
"approach": "Add 404, 401/403, and 429 branches inside the existing urllib.error.HTTPError handler in read_llm_provider_json. Each branch keeps the provider_label and redacted body suffix, but appends a one-line root-cause + one-line recovery command. The fallback raise at the end is preserved for every other status code. No public surface changes outside the SystemExit message text: same function signature, same callers (openai_compatible_chat_completion line 10731, ollama_chat_completion line 10759), same exit code.",
"files_expected": [
"src/spark_cli/cli.py"
],
"tests_or_smoke": "Smoke: run the affected code path in the repo and confirm before\u2192after behavior change. Build-clean:
python3 -m py_compile src/spark_cli/cli.pyornpx tsc --noEmit --skipLibCheck src/spark_cli/cli.py."},
"pr": {
"url": "#1047",
"branch": "spark-compete/read-llm-provider-classify-404",
"title_prefix": "[spark-compete]",
"author_github": "4gjnbzb4zf-sudo",
"body_must_include": [
"packet",
"team",
"pr_author",
"repo",
"actual_behavior",
"expected_behavior",
"repro_steps",
"before_after_proof",
"tests_or_smoke",
"duplicate_notes",
"risk_notes",
"review_claim"
]
},
"review_claim": {
"impact_claim": "low",
"evidence_types": [
"redacted_terminal_excerpt",
"code_path_trace"
],
"duplicate_notes": "Searched open PRs and issues for the same defect; this fix is targeted to src/spark_cli/cli.py.",
"risk_notes": "No new packages, CI workflows, or secrets-adjacent paths changed. Diff is bounded to src/spark_cli/cli.py. Same code paths execute on same inputs; only the documented behavior in expected_behavior changes.",
"review_state_requested": "pr_review"
}
}