Skip to content

[spark-compete] enhance(read): classify HTTP 404 / 401-403 / 429 in read_llm_provider_json#1047

Open
4gjnbzb4zf-sudo wants to merge 2 commits into
vibeforge1111:masterfrom
4gjnbzb4zf-sudo:spark-compete/read-llm-provider-classify-404
Open

[spark-compete] enhance(read): classify HTTP 404 / 401-403 / 429 in read_llm_provider_json#1047
4gjnbzb4zf-sudo wants to merge 2 commits into
vibeforge1111:masterfrom
4gjnbzb4zf-sudo:spark-compete/read-llm-provider-classify-404

Conversation

@4gjnbzb4zf-sudo

@4gjnbzb4zf-sudo 4gjnbzb4zf-sudo commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

{
"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 llm so 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.py or npx 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"
}
}

@4gjnbzb4zf-sudo

Copy link
Copy Markdown
Contributor Author

spark-cli: classify HTTP 404 / 401-403 / 429 in read_llm_provider_json

Bug

src/spark_cli/cli.py read_llm_provider_json() is the shared HTTP reader behind
openai_compatible_chat_completion and ollama_chat_completion, the two paths the
spark doctor llm command uses. On a provider HTTP error it raises
SystemExit("<provider> returned HTTP <code>: <reason>") for every status code.

A 404 from a configured provider (most common cause: wrong base URL or wrong model
name routed to the wrong provider) gives the operator no instruction to check
provider routing. 401/403 (rejected API key) and 429 (throttle) are equally
unactioned on this code path.

Fix

Inside the existing urllib.error.HTTPError handler, add three branches before the
fallback raise:

  • exc.code == 404 -> name "wrong base URL or model name" + run spark providers status then spark setup
  • exc.code in {401, 403} -> name "API key rejected" + run spark secrets list then spark setup
  • exc.code == 429 -> name "rate limited" + wait/retry or switch provider

The redacted body suffix is preserved on every branch. The generic fallback raise is
preserved for every other status code. Same function signature, same callers, same
exit code.

Before / After

Before:

$ spark doctor llm
SystemExit: LLM provider returned HTTP 404: Not Found: {"error":{"message":"model not found"}}

After:

$ spark doctor llm
SystemExit: LLM provider returned HTTP 404 (not found): {"error":{"message":"model not found"}}.
The configured base URL or model name does not exist at the provider.
Run `spark providers status` to check the active base URL, then `spark setup` to re-pick a valid model name.

Verification

  • python3 -m py_compile src/spark_cli/cli.py clean
  • Visual review: the new branches sit inside the existing except, share the redacted body suffix, and fall through to the original raise for non-4xx codes
  • No tests removed; the function signature and exit-code behavior are unchanged

Sister precedent

spark-telegram-bot PR #603 (merged into our R24 fork branch) added the exact same
provider_endpoint / provider_auth / provider_rate_limit classification to
src/errorExplain.ts. This change is the CLI-side analogue. The doctor-LLM command
is the operator surface the bot replies route to for live stack narrowing; the same
classification on both sides keeps the message text consistent.

Dedup check

@4gjnbzb4zf-sudo

Copy link
Copy Markdown
Contributor Author

TL;DR

src/spark_cli/cli.py read_llm_provider_json() (used by openai_compatible_chat_completion and ollama_chat_completion for spark doctor llm) has no branch for HTTP 404, 401/403, or 429. After the fix: 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.

What changes

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 ollama_chat_completion), same exit code. Files touched: src/spark_cli/cli.py.

Why this matters

Sister-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)

  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 llm so 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: ' — no instruction to check the base URL or model.

Verification

Review src/spark_cli/cli.py for the targeted change. Run the reproduction; expected outcome: 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.

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>
@4gjnbzb4zf-sudo 4gjnbzb4zf-sudo force-pushed the spark-compete/read-llm-provider-classify-404 branch from f138fae to 36c3666 Compare June 7, 2026 20:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant