can1357/oh-my-pi · error · anyhow::Error
Unsupported language '{value}'. Supported: {}
Error message
Unsupported language '{value}'. Supported: {} What it means
The RPC client validates todo item seeds passed to set_todos() against the known TodoStatus enum (_TODO_STATUS_VALUES). If a seed dict carries a 'status' string that is not one of the supported statuses, RpcError is raised before anything is sent to the server. This fails fast so invalid state never reaches the RPC peer.
Source
Thrown at crates/pi-ast/src/ops.rs:73
#[derive(Debug, Clone)]
pub struct CompiledRewrite {
pub out: String,
pub patterns: Vec<Pattern>,
}
#[must_use]
pub fn resolve_strictness(value: Option<AstMatchStrictness>) -> MatchStrictness {
value.map_or(MatchStrictness::Smart, Into::into)
}
#[must_use]
pub fn supported_lang_list() -> String {
SupportLang::sorted_aliases().join(", ")
}
pub fn resolve_supported_lang(value: &str) -> Result<SupportLang> {
SupportLang::from_alias(value).ok_or_else(|| {
anyhow!("Unsupported language '{value}'. Supported: {}", supported_lang_list())
})
}
pub fn resolve_language(lang: Option<&str>, file_path: &Path) -> Result<SupportLang> {
if let Some(lang) = lang.map(str::trim).filter(|lang| !lang.is_empty()) {
return resolve_supported_lang(lang);
}
SupportLang::from_path(file_path).ok_or_else(|| {
anyhow!(
"Unable to infer language from file extension: {}. Specify `lang` explicitly.",
file_path.display()
)
})
}
#[must_use]
pub fn is_supported_file(file_path: &Path, explicit_lang: Option<&str>) -> bool {
if explicit_lang.is_some() {View on GitHub (pinned to 9690622007)
Solutions
- Use one of the exact TodoStatus string values the library defines (check _TODO_STATUS_VALUES in omp_rpc/client.py).
- Normalize/trim incoming status strings and map external vocabularies to TodoStatus before calling set_todos().
- Omit 'status' entirely so the seed defaults to "pending" (the non-string branch).
- Wrap set_todos() in try/except RpcError to surface a friendly validation message.
Example fix
// before
client.set_todos([{"id": "t1", "title": "Fix bug", "status": "in-progress"}])
// after
client.set_todos([{"id": "t1", "title": "Fix bug", "status": "in_progress"}]) Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = {"pending", "in_progress", "completed", "cancelled"} # mirror _TODO_STATUS_VALUES
raw = seed.get("status")
if isinstance(raw, str) and raw not in ALLOWED:
raise ValueError(f"todo status {raw!r} not one of {sorted(ALLOWED)}") Type guard
def is_todo_status(v: object) -> TypeGuard[str]:
return isinstance(v, str) and v in _TODO_STATUS_VALUES Try / catch
try:
client.set_todos(seeds)
except RpcError as exc:
if "Unsupported todo status" in str(exc):
logger.warning("bad todo status: %s", exc)
else:
raise Prevention
- Always assign statuses from the TodoStatus literal type, never free strings.
- Normalize/strip external status vocabularies via a mapping table before set_todos().
- Omit 'status' when you mean pending — the default branch handles it.
When it happens
Trigger: Calling set_todos() with a seed dict whose 'status' is a string not in _TODO_STATUS_VALUES, e.g. status="in-progress" when the library expects "in_progress", or a typo like "done " with trailing whitespace, or an arbitrary free-form status from user input.
Common situations: Hand-writing todo JSON with kebab-case statuses, importing todos from another tool that uses different status vocabulary, or piping user-supplied status strings straight into set_todos() without normalizing.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Unsupported todo status: {seed.status}
- Unable to infer language from file extension: {}. Specify `l
- Invalid pattern: {err}
- Todo items must provide a non-empty 'content' value
- {field} must be one of: {expected}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/06f8160f5606eb03.
Report an issue: GitHub.