keras-team/keras · error · ValueError
Cannot concatenate features because feature '{name}' has not
Error message
Cannot concatenate features because feature '{name}' has not been encoded (it has dtype {dtype}). Consider using `output_mode='dict'`. What it means
In output_mode='concat', FeatureSpace concatenates all features into one float tensor. If a feature still has an integer or string dtype it was never encoded (e.g. a crossing with output_mode='int' left raw), and concatenation is impossible. Set an encoding output mode or use 'dict' output.
Source
Thrown at keras/src/layers/preprocessing/feature_space.py:721
else:
raise ValueError(
f"Feature '{name}' has `output_mode='one_hot'`. "
"However it isn't a standard feature and the "
"dimensionality of its output space is not known, "
"thus it cannot be one-hot encoded. "
"Try using `output_mode='int'`."
)
if cardinality is not None:
encoder = layers.CategoryEncoding(
num_tokens=cardinality, output_mode="multi_hot"
)
self.one_hot_encoders[name] = encoder
feature = encoder(feature)
if self.output_mode == "concat":
dtype = feature.dtype
if dtype.startswith("int") or dtype == "string":
raise ValueError(
f"Cannot concatenate features because feature '{name}' "
f"has not been encoded (it has dtype {dtype}). "
"Consider using `output_mode='dict'`."
)
features_to_concat.append(feature)
else:
output_dict[name] = feature
if self.output_mode == "concat":
self.concat = TFDConcat(axis=-1)
return self.concat(features_to_concat)
else:
return output_dict
def _check_if_adapted(self):
if not self._is_adapted:
if not self._list_adaptable_preprocessors():
self._is_adapted = TrueView on GitHub (pinned to 7a34a03db6)
Solutions
- Set crossing_output_mode='one_hot' (or FeatureSpace output_mode='one_hot') so cross features get encoded before concat
- Use output_mode='dict' if you want raw per-feature outputs
- Verify each feature's spec produces encoded (float) output when concatenating
Example fix
// before fs = FeatureSpace(..., output_mode="concat") # crossing_output_mode='int' default // after fs = FeatureSpace(..., output_mode="concat", crossing_output_mode="one_hot") # or use output_mode="dict" for raw outputs
Defensive patterns
Strategy: validation
Validate before calling
p = fs.preprocessors.get(name) or fs.crossers.get(name)
out = p(sample_batch)
assert not (str(out.dtype).startswith("int") or str(out.dtype) == "string"), f"{name} unencoded for concat" Type guard
def is_encoded(name, feature_space):
return not (name in feature_space.crossers and getattr(feature_space, "crossing_output_mode", "int") == "int" and feature_space.output_mode == "concat") Try / catch
catch ValueError from get_encoded_features()/__call__, then either set an encoding output_mode or switch FeatureSpace to output_mode='dict'
Prevention
- Set crossing/output_mode='int' or 'one_hot' so every feature is encoded before concat
- Use output_mode='dict' when you want raw (unencoded) feature outputs
When it happens
Trigger: FeatureSpace(output_mode='concat') while a feature or crossing produces raw int/string output, typically crossing_output_mode='int' left at default with concat output.
Common situations: Leaving crossing_output_mode='int' while FeatureSpace output_mode='concat'; forgetting to set output_mode on the FeatureSpace so unencoded integer lookups flow into concat.
Related errors
- `adapt()` can only be called on a tf.data.Dataset or a dict
- Feature '{name}' has `output_mode='one_hot'`. Thus its prepr
- Feature '{name}' has `output_mode='one_hot'`. However it isn
- You need to call `.adapt(dataset)` on the FeatureSpace befor
- A FeatureSpace can only be called with a dict. Received: dat
AI-assisted analysis of keras-team/keras@7a34a03db6 (2026-08-25).
Data as JSON: /api/errors/724a1e78ca564f99.
Report an issue: GitHub.