ZhuLinsen/daily_stock_analysis · error · GenerationError
unsafe_config
unsafe_config
Error message
unsafe_config at configuration for backend {backend} What it means
A structured GenerationError with code unsafe_config raised at the configuration stage when resolve_local_cli_preset cannot find the requested preset_id in SAFE_LOCAL_CLI_PRESETS. Presets are an explicit allowlist of vetted local CLI configurations; unknown IDs are rejected as unsafe rather than silently defaulted. It is non-retryable and non-fallbackable by design.
Source
Thrown at src/llm/local_cli_backend.py:2040
for event in events:
event_type_lower = str(event.get("type") or "").strip().lower()
if (
_opencode_blocked_event_reason(event, event_type_lower)
or bool(event.get("error"))
or event.get("is_error") is True
):
return True
except LocalCliExtractionError:
return False
return False
def resolve_local_cli_preset(preset_id: str) -> LocalCliPreset:
"""Return a safe preset or raise a structured unsafe_config error."""
preset = SAFE_LOCAL_CLI_PRESETS.get((preset_id or "").strip().lower())
if preset is None:
raise GenerationError(
error_code=GenerationErrorCode.UNSAFE_CONFIG,
stage="configuration",
retryable=False,
fallbackable=False,
backend=preset_id or "local_cli",
provider=preset_id or "local_cli",
details={
"reason": "unknown_local_cli_preset",
"preset_id": preset_id,
"allowed_presets": sorted(SAFE_LOCAL_CLI_PRESETS),
},
)
return preset
class LocalCliGenerationBackend(GenerationBackend):
"""Restricted subprocess-backed generation backend."""
View on GitHub (pinned to 5159bd72e8)
Solutions
- Read the allowed_presets list from the error details (or inspect SAFE_LOCAL_CLI_PRESETS) and set the preset ID to one of those exact values
- Fix typos, casing, and stray whitespace in the configured preset ID (normalization only handles case and surrounding whitespace)
- If the preset was renamed, update the config to the new identifier from the current codebase
- Upgrade or pin the deployment so its allowlist matches the preset the config references
Example fix
# before LOCAL_CLI_PRESET=claudecode # after LOCAL_CLI_PRESET=claude-code # must match an entry in SAFE_LOCAL_CLI_PRESETS
Defensive patterns
Strategy: validation
Validate before calling
from src.llm.local_cli_backend import SAFE_LOCAL_CLI_PRESETS
def is_known_preset(preset_id: str) -> bool:
return (preset_id or "").strip().lower() in SAFE_LOCAL_CLI_PRESETS Type guard
from typing import Any
from src.llm.local_cli_backend import SAFE_LOCAL_CLI_PRESETS
def is_safe_preset_id(value: Any) -> bool:
return isinstance(value, str) and value.strip().lower() in SAFE_LOCAL_CLI_PRESETS Try / catch
try:
preset = resolve_local_cli_preset(preset_id)
except GenerationError as exc:
if exc.error_code == GenerationErrorCode.UNSAFE_CONFIG:
log.error("Unknown preset %r; allowed: %s", preset_id, exc.details["allowed_presets"])
raise Prevention
- Expose allowed preset IDs in UI dropdowns / config docs so users cannot type free text
- Validate preset IDs at config load, not at generation time
- Treat preset renames as breaking config changes and migrate stored settings on upgrade
When it happens
Trigger: Calling resolve_local_cli_preset('claude-code') (or any ID not in the allowlist), passing an empty or misspelled preset string, or passing a casing/whitespace variant not covered by the .strip().lower() normalization. The details payload includes reason=unknown_local_cli_preset and the sorted list of allowed presets.
Common situations: A config file or env var names a preset removed in a refactor; user typos in LOCAL_CLI_PRESET; version mismatch where the deployed code has a smaller allowlist than the config expects; copy-pasting a preset ID from newer docs into an older install.
Related errors
- Responses API surface requires a normalized openai/<model> r
- LLM route aliases cannot mix API surfaces: {sorted(surface_c
- Hermes only supports PROTOCOL=openai
- Hermes BASE_URL must point to 127.0.0.1, localhost, or [::1]
- Hermes BASE_URL contains an invalid port
AI-assisted analysis of ZhuLinsen/daily_stock_analysis@5159bd72e8 (2026-08-15).
Data as JSON: /api/errors/5a0e82b73867e305.
Report an issue: GitHub.