databendlabs/databend · error · ValueError
Token does not belong to this ContextVar
Error message
Token does not belong to this ContextVar
What it means
This is a proc-macro compile-time error from derive(Visit)/derive(WalkMut): the visitor derive supports structs and enums but has no implementation for Rust unions. Applying the derive to a union type aborts compilation with this message at the union's span.
Solutions
- Remove the Walk/Visit derive from the union and implement the visitor manually.
- Restructure the type as an enum or struct instead of a union.
- Wrap the union in a newtype struct/enum that carries a manual Walk impl.
Example fix
// before
#[derive(Visit)]
union Raw { i: u64, f: f64 }
// after
impl<'ast> Visit<'ast> for Raw { /* manual impl */ } Defensive patterns
Strategy: type-guard
Validate before calling
// compile-time: ensure derive targets are struct or enum
const _: () = { assert!(std::mem::size_of::<MyType>() > 0); }; // cannot detect union at runtime; check the source type before deriving Prevention
- Never apply Walk/Visit derives to unions
- Recheck derive lists when converting enums to unions
- Prefer enums over unions for AST-adjacent types
When it happens
Trigger: Annotating a `union` definition with #[derive(Visit)] or #[derive(WalkMut)] in the query AST codebase.
Common situations: Refactoring an enum/struct into a union for FFI or memory-layout reasons while keeping the derive; copy-pasting a derive list onto a new union type.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- MEMORY_EXCEEDS_LIMIT
- verifier did not complete within the timeout.
- invalid engine
- Unsupported format for
- Unsupported source type. Expected path, pandas.DataFrame…
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/e8b5a929e9865fd9.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/script_udf_support/src/transform_udf_script.rs:650
def get(self, default=_MISSING):
value = getattr(self._local, "value", _MISSING)
if value is _MISSING:
if default is not _MISSING:
return default
if self.default is _MISSING:
raise LookupError(f"ContextVar {self.name} has no value")
return self.default
return value
def set(self, value):
old = getattr(self._local, "value", _MISSING)
self._local.value = value
return Token(self, old)
def reset(self, token):
if token.var is not self:
raise ValueError("Token does not belong to this ContextVar")
if token.old is _MISSING:
if hasattr(self._local, "value"):
del self._local.value
else:
self._local.value = token.old
class Context:
def __init__(self, values=None):
self._values = values or {}
def __setitem__(self, key, value):
self._values[key] = value
def items(self):
return self._values.items()
def run(self, callable, *args, **kwargs):
tokens = []View on GitHub (pinned to 288d84d76e)