#ConfigError
One YAML field.
Two apps down at once.

Full postmortem on how a copied config file broke OpenCode's CLI and Desktop together: istiquritconsultant.com/workflow-opt...

#OpenCode #AIcoding #DevTools #YAML #ConfigError #DebuggingTips #WorkflowOptimization #AIWorkflow #TechDiary
September 15, 2026 at 6:54 AM
Help understanding a error
I am trying to use wrapper around different kind of errors so I don't have to worry about returning specific errors for each function. Here is implementation I managed to dig out from ai code tools. use std::{error::Error as StdError, fmt, io}; use crossterm::ErrorKind as CrosstermErrorKind; #[derive(Debug)] pub enum EditorError { Io(io::Error), Crossterm(CrosstermErrorKind), ConfigError(Box<dyn StdError + Send + Sync>), } impl fmt::Display for EditorError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { EditorError::Io(e) => write!(f, "IO error: {}", e), EditorError::Crossterm(e) => write!(f, "Crossterm error: {}", e), EditorError::ConfigError(e) => write!(f, "Config error: {}", e), } } } impl StdError for EditorError {} impl From<io::Error> for EditorError { fn from(err: io::Error) -> Self { EditorError::Io(err) } } impl From<CrosstermErrorKind> for EditorError { fn from(err: CrosstermErrorKind) -> Self { EditorError::Crossterm(err) } } impl From<Box<dyn StdError + Send + Sync>> for EditorError { fn from(err: Box<dyn StdError + Send + Sync>) -> Self { EditorError::ConfigError(err) } } pub type Result<T> = std::result::Result<T, EditorError>; I get this error ? error[E0119]: conflicting implementations of trait `From<std::io::Error>` for type `EditorError` --> src\utils\error.rs:29:1 | 23 | impl From<io::Error> for EditorError { | ------------------------------------ first implementation here ... 29 | impl From<CrosstermErrorKind> for EditorError { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `EditorError`**** How is io:Error same as CrosstermErrorKind. Is it due to some aliasing. Is this kind of overloading not allowed. I am new to rust so I am trying to understand. Any help will be greatly appreciated. Also any pointers to how to in general debug these kind of issues ?
users.rust-lang.org
May 14, 2025 at 10:37 PM
Rust is like java
The ask seems to be isolation of error types that are allowed to occur in specific parts of a function. I admit I have never had such a desire. Isolating part of a function to only return one specific kind of error is done by factoring that part into a new subroutine with its own error type. fn load_config(path: &Path) -> Result<Config, ConfigError> { let json = load_json(path)?; Config::try_from(json) } fn load_json(path: &Path) -> Result<Json, JsonError> { todo!() } An alternative interpretation is that error handling should be done inline, rather than bubbling the error to the caller. For example, by loading a default value if a file was missing or there was a parse error. fn load_config(path: &Path) -> Result<Config, ConfigError> { let config = load_json(path).map(Config::try_from).unwrap_or_default(); Ok(config) } Both of these can be done today without hitting the checked exception problem in Java. Soni: > in fact we hate the idea of shoving errors inside errors. rust does that a lot, that's how you end up with 1GB error structs. We should be careful about over exaggeration, as that can harm the credibility of the claim. There is no inherent requirement for error types to be nested. The `?` operator can perform a pure transformation as errors bubble up the call stack, including ZST to ZST. The reason errors tend to be nested in practice is because error handling is complex. The more contextual information provided with the error, the more likely it is for a human to understand the issue and seek a solution. I don't feel strongly that a new syntax will greatly improve error handling. And I am unconvinced that there is a problem to solve. `Result` is nothing like a Java checked exception.
users.rust-lang.org
November 27, 2024 at 10:02 PM
you can also unify some things, e.g. if you parameterize over

E: From<TokenizerError> + From<std::io::Error>

the top-level error can unify all IO errors under one category instead of having a bucket in each error type

ConfigError {
TokenizerError(...)
ParserError(...)
IOError(...)
}
August 1, 2024 at 3:51 AM
then the caller can pick whatever representation they want

you might have

ConfigError {
TokenError(#[from]TokenError),
ParserError(#[from]ParserError),
SemanticError(#[from]SemanticError),
ValidationError(#[from]ValidationError),
}

the ? syntax will automatically convert where needed
August 1, 2024 at 3:48 AM