zed-industries/zed · error
operands of != must be identifiers
Error message
operands of != must be identifiers
What it means
new_neq mirrors new_eq: '!=' is only defined between two Identifier predicates because evaluation resolves the left identifier's value and compares it for inequality. A composite operand (group, &&/|| chain, '>' descendant, negation) on either side makes the constructor bail.
Source
Thrown at crates/gpui/src/keymap/context.rs:443
}
fn new_child(self, other: Self) -> Result<Self> {
Ok(Self::Descendant(Box::new(self), Box::new(other)))
}
fn new_eq(self, other: Self) -> Result<Self> {
if let (Self::Identifier(left), Self::Identifier(right)) = (self, other) {
Ok(Self::Equal(left, right))
} else {
anyhow::bail!("operands of == must be identifiers");
}
}
fn new_neq(self, other: Self) -> Result<Self> {
if let (Self::Identifier(left), Self::Identifier(right)) = (self, other) {
Ok(Self::NotEqual(left, right))
} else {
anyhow::bail!("operands of != must be identifiers");
}
}
fn fmt_joined(
&self,
f: &mut fmt::Formatter<'_>,
separator: &str,
operator: LogicalOperator,
needs_parens: impl Fn(&Self) -> bool + Copy,
) -> fmt::Result {
let mut first = true;
self.fmt_joined_inner(f, separator, operator, needs_parens, &mut first)
}
fn fmt_joined_inner(
&self,
f: &mut fmt::Formatter<'_>,
separator: &str,View on GitHub (pinned to f4178619ac)
Solutions
- Keep both sides of != as bare identifiers: mode != normal
- Express multi-value exclusion as a chain: (mode != normal && mode != visual)
- Place negation outside the whole comparison if needed: !(mode == normal)
Example fix
// before (keymap.json) "context": "mode != (normal || visual)" // after "context": "(mode != normal && mode != visual)"
Defensive patterns
Strategy: validation
Validate before calling
KeyBindingContextPredicate::parse("(mode != normal && mode != visual)")?; // validate before install Type guard
fn is_parseable_context(source: &str) -> bool {
KeyBindingContextPredicate::parse(source).is_ok()
} Prevention
- Remember == and != combine identifiers only
- Express multi-value exclusion as chained != comparisons
- Put negation outside the whole comparison: !(mode == normal)
When it happens
Trigger: Writing 'mode != (a || b)', '(a && b) != c', or '!a != b' — any != whose operands are not both identifiers.
Common situations: Negated comparisons against multiple values; mixing precedence parentheses into inequality expressions; porting boolean shapes from other tools.
Related errors
- operands of == must be identifiers
- unexpected character '{next:?}'
- invalid RGBA hex color: '{value}'. Expected #rgb, #rgba, #rr
- Device lost: {err}
- database not initialized
AI-assisted analysis of zed-industries/zed@f4178619ac (2026-08-20).
Data as JSON: /api/errors/c70fc5c0699e29b9.
Report an issue: GitHub.