vllm-project/vllm · error · Error

failed to build structural tag: {message}

Error message

failed to build structural tag: {message}

What it means

Wraps failures from building a structural-tag guided-decoding grammar (`output/default/structural_tag.rs:53` maps the underlying error into this variant with a `message`). Structural tags combine triggers, JSON schemas, and output formats into a grammar; building that grammar can fail on invalid schemas, bad triggers, or grammar-compiler errors.

Source

Thrown at rust/src/chat/src/error.rs:80

        #[source]
        error: BoxedError,
    },
    #[error(
        "this model's maximum context length is {max_model_len} tokens, \
         but the prompt contains {prompt_len} input tokens"
    )]
    PromptTooLong { max_model_len: u32, prompt_len: u32 },
    #[error("chat request stream `{request_id}` closed before terminal output")]
    StreamClosedBeforeTerminalOutput { request_id: String },
    #[error("tool call stream state is inconsistent: {message}")]
    ToolCallStreamInvariant { message: String },
    #[error("duplicate tool name `{name}`")]
    DuplicateToolName { name: String },
    #[error("tool_choice requires at least one available tool")]
    ToolChoiceRequiresTools,
    #[error("tool_choice function `{name}` was not found in the available tools")]
    ToolChoiceFunctionNotFound { name: String },
    #[error("failed to build structural tag: {message}")]
    StructuralTag { message: String },
    #[error(transparent)]
    Text(#[from] vllm_text::Error),
    #[error(transparent)]
    Tokenizer(#[from] vllm_tokenizer::TokenizerError),
}

pub type Result<T> = std::result::Result<T, Error>;

impl Error {
    /// Whether this error represents invalid user request parameters.
    pub fn is_request_validation_error(&self) -> bool {
        match self {
            Self::PromptTooLong { .. }
            | Self::DuplicateToolName { .. }
            | Self::ToolChoiceRequiresTools
            | Self::ToolChoiceFunctionNotFound { .. } => true,
            Self::Text(error) => error.is_request_validation_error(),

View on GitHub (pinned to c794754062)

Solutions

  1. Read `{message}` — it contains the underlying compiler error naming the offending field.
  2. Validate each structural-tag component separately: triggers are non-empty valid strings, schema is valid JSON Schema, format placeholders match schema properties.
  3. Simplify the structural tag to a minimal repro, then re-add components until the failure reappears.
  4. If the grammar compiler is at fault, fall back to guided_json mode for the request.

Example fix

// before
StructuralTag {
    schema: broken_schema, // missing "type"
    triggers: vec![],
    format: "{answer}",
}

// after
StructuralTag {
    schema: serde_json::from_str(VALID_SCHEMA)?, // checked Draft-07 schema with "answer"
    triggers: vec!["<answer>".into()],
    format: "<answer>{answer}</answer>",
}
Defensive patterns

Strategy: validation

Validate before calling

for tag in &structural_tags {
    debug_assert!(!tag.triggers.is_empty(), "structural tag needs a trigger");
    jsonschema::compile(&tag.schema)?; // fail fast on invalid schema
}

Try / catch

match result {
    Err(vllm_chat::Error::StructuralTag { message }) => {
        tracing::error!(%message, "structural tag build failed");
        respond_bad_request(format!("invalid structural tag: {message}"))
    }
    other => other?,
}

Prevention

When it happens

Trigger: Using the structural-tag output mode (OpenAI-style `structural_tag` / guided structural output) where the provided schema, trigger strings, or format specification cannot be compiled into a valid grammar by the guided-decoding backend.

Common situations: Malformed JSON schema inside the structural tag spec; empty or regex-invalid trigger patterns; mismatch between the schema and the format section (e.g. placeholders the format references that the schema does not define).

Related errors


AI-assisted analysis of vllm-project/vllm@c794754062 (2026-08-14). Data as JSON: /api/errors/b2e65324afa20ea7. Report an issue: GitHub.