denoland/deno · error · syn::Error
Cannot combine `untagged` with `tag` or `content`
Error message
Cannot combine `untagged` with `tag` or `content`
What it means
#[derive(ToV8)] supports several tagging modes set at the container level: #[to_v8(tag = "...")] (internally tagged), adding #[to_v8(content = "...")] (adjacently tagged), and #[to_v8(untagged)]. When untagged is combined with tag or content, the modes contradict (untagged emits no tag at all), so parse_enum_mode returns this compile error at the call site.
Source
Thrown at libs/ops/conversion/to_v8/enum.rs:264
let args = list.parse_args_with(
Punctuated::<EnumModeArgument, Token![,]>::parse_terminated,
)?;
for arg in args {
match arg {
EnumModeArgument::Tag { value, .. } => tag = Some(value.value()),
EnumModeArgument::Content { value, .. } => {
content = Some(value.value())
}
EnumModeArgument::Untagged { .. } => untagged = true,
}
}
}
}
if untagged {
if tag.is_some() || content.is_some() {
return Err(Error::new(
Span::call_site(),
"Cannot combine `untagged` with `tag` or `content`",
));
}
return Ok(EnumMode::Untagged);
}
match (tag, content) {
(None, None) => Ok(EnumMode::ExternallyTagged),
(Some(tag), None) => Ok(EnumMode::InternallyTagged {
tag: crate::get_internalized_string(Ident::new(&tag, span))?,
}),
(Some(tag), Some(content)) => Ok(EnumMode::AdjacentlyTagged {
tag: crate::get_internalized_string(Ident::new(&tag, span))?,
content: crate::get_internalized_string(Ident::new(&content, span))?,
}),
(None, Some(_)) => Err(Error::new(
Span::call_site(),View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Decide the mode: keep #[to_v8(untagged)] alone, or remove untagged and keep tag (optionally with content).
- If you need per-variant control, use rename/serde attributes on variants instead of mixing container modes.
Example fix
// before
#[derive(ToV8)]
#[to_v8(untagged, tag = "kind")] // error: Cannot combine `untagged` with `tag` or `content`
enum Value {
Num(u32),
Str(String),
}
// after
#[derive(ToV8)]
#[to_v8(untagged)]
enum Value {
Num(u32),
Str(String),
} Defensive patterns
Strategy: validation
Prevention
- Pick exactly one tagging mode per enum: default (externally tagged), tag (internally), tag+content (adjacently), or untagged — never combinations.
- When migrating a serde enum, translate its tagging attributes one-to-one instead of stacking all of them.
When it happens
Trigger: Writing #[to_v8(untagged, tag = "kind")] or #[to_v8(untagged, content = "data")] on an enum derived with ToV8.
Common situations: Migrating a serde enum that used both untagged and tag-like attributes; merging attributes from two examples; editing a tagged enum to untagged and forgetting to delete the old tag/content arguments.
Related errors
- Cannot use serde on unit variant
- `content` requires `tag` to be specified
- FromV8 enum derive currently supports only unit and single-e
- Unions are not supported
- Unit structs cannot be destructured
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/04e7adf8584a5dca.
Report an issue: GitHub.